0

I have a visualforce page located on the case object that shows a table with assets that are related to that case. From the asset table you can update the asset serial number, click the custom save button and the asset serial number updates and saves.

The issue I am running into is that I added a checkbox to the asset table from the related case. When the checkbox is checked in the asset table and the save button is clicked the checkbox field on the case does not update or save.

Here is my visualforce page code.

<apex:page standardController="Case" extensions="pullEquipmentUpdateAssetClass">     
    <p></p>
    <apex:pageblock id="Assets">
         <br/> 
            <apex:form > 
                <apex:pageBlockTable value="{!Assets}" var="asset">
                    <apex:column value="{!asset.Product_Code_Display__c}"/>
                    <apex:column value="{!asset.Product_Description_Display__c}"/> 
                    <apex:column value="{!asset.Delivery_Address__c}"/>
                    <apex:column value="{!asset.Serial_Number_Procurement__c}"/>
                    <apex:column headerValue="Serial Number"><apex:inputText value="{!asset.Serial_Number_Procurement__c}" required="true" /></apex:column>
                    <!-- this checkbox can be checked, but when the save button is clicked the checkbox field on the case does not update -->
                    <apex:column headerValue="Equipment has been pulled"><apex:inputCheckbox value="{!asset.Child_Fulfillment_Ticket__r.Equipment_Has_Been_Pulled__c}"/></apex:column>
                 </apex:pageBlockTable>
                <apex:commandButton value="Save" action="{!saveSerialIdNumber}"/>
        </apex:form>
    </apex:pageblock>
</apex:page>

And here is my apex class:

public class pullEquipmentUpdateAssetClass {
    public List<Asset> Assets{get;set;}
    public Case Cases {get;set;} 
    public Case c {get;set;} 

    //Constructor 
     public pullEquipmentUpdateAssetClass(ApexPages.StandardController controller) { 
        c = (Case)controller.getRecord();      
        Cases = [SELECT id, Equipment_Has_Been_Pulled__c FROM Case WHERE id=: c.id LIMIT 1]; 
        Assets = [SELECT id,Child_Fulfillment_Ticket__r.Equipment_Has_Been_Pulled__c,Serial_Number_Procurement__c,Name,Delivery_Address__c,Product_Code_Display__c,Product_Description_Display__c FROM Asset WHERE Serialized__c = true AND Child_Fulfillment_Ticket__c = :Cases.id]; 
     } 

    //save button for serial number
    public PageReference saveSerialIdNumber(){
        update Assets;
        update Cases;
        Assets = [SELECT id,Child_Fulfillment_Ticket__r.Equipment_Has_Been_Pulled__c,Serial_Number_Procurement__c,Name,Delivery_Address__c,Product_Code_Display__c,Product_Description_Display__c FROM Asset WHERE Serialized__c = true AND Child_Fulfillment_Ticket__c = :Cases.id]; 
        Cases = [SELECT id,Equipment_Has_Been_Pulled__c FROM Case WHERE id=: c.id];
        return ApexPages.currentPage();
    }
}

I am still fairly new to apex, so I am not super familiar with it

3
  • To which objectc is Child_Fulfillment_Ticket__r pointing to? Jun 8 '20 at 20:00
  • Child_Fulfillment_Ticket__r is a lookup field on the asset that points to the case
    – Ian
    Jun 8 '20 at 20:43
  • What is the Child Relationship Name for that lookup? Jun 8 '20 at 23:50
0

I believe your problem is that you are trying to update a field inside the Case through a DML on the Asset sObject.

Conceptually its odd, because you are showing a checkbox on all the lines of the table, which belongs to the same Case Record.

(What happens if the table has more than one row and some of the records has it to true and some to false? What would be the real value?)

My suggestion is to put the input checkbox outside the table and use it directly from the case object (not navigating through the Asset's lookup).

I don't know if there are some other pieces of code, but with what you are sharing I don't quite get the need of having c and cases. When you use the standard controller, salesforce automatically fetches the fields that are used on the visualforce.

I would personally take more advantage from the Standard controller and simplify your extension a bit like below (You just need to figure out which is your "Child Relationship Name" for the lookup field and replace YourChildRelationshipName__r with it.

Page

<apex:page standardController="Case" extensions="pullEquipmentUpdateAssetClass">     
    <p></p>
    <apex:form > 
        <apex:pageblock id="Assets">
        
            <apex:pageBlockSection columns="1"> <!-- to allow the apex:input to show the label -->
                <apex:pageBlockTable value="{!Case.YourChildRelationshipName__r}" var="asset">
                    <apex:column value="{!asset.Product_Code_Display__c}"/>
                    <apex:column value="{!asset.Product_Description_Display__c}"/> 
                    <apex:column value="{!asset.Delivery_Address__c}"/>
                    <apex:column value="{!asset.Serial_Number_Procurement__c}"/>
                    <apex:column headerValue="{!$ObjectType.Asset.fields.Serial_Number_Procurement__c.label}"><!-- to take the label dynamically -->
                        <apex:inputText value="{!asset.Serial_Number_Procurement__c}" required="true" />
                    </apex:column>
                </apex:pageBlockTable>
                
                <apex:inputCheckbox value="{!Case.Equipment_Has_Been_Pulled__c}"/>
            </apex:pageBlockSection>
            <apex:pageBlockButtons location="bottom">                
                <apex:commandButton value="Save" action="{!saveSerialIdNumber}"/>
            </apex:pageBlockButtons>
        </apex:pageblock>
    </apex:form>
</apex:page>

Extension

public class pullEquipmentUpdateAssetClass {
    private ApexPages.StandardController controller;

    //Constructor 
    public pullEquipmentUpdateAssetClass(ApexPages.StandardController controller) {
        this.controller = controller;
    }

    public void saveSerialIdNumber() {
        // here we use the standard controller's capability of fetching related records to update them ourselves 
        // (Casting is needed because YourChildRelationshipName__r is specific to your case object)
        update ((Case) controller.getRecord()).YourChildRelationshipName__r;
        // here we call the standard controller's "update"
        controller.save();
    }
}
1
  • Thank you Sergio! That worked. You are right, I didn't think it all the way through because it doesn't make much sense to have the check box on every line.
    – Ian
    Jun 9 '20 at 16:03
0

Two modifications:

 <apex:commandButton value="Save" action="{!saveSerialIdNumber}" immediate="true"/>

Apex extension

//save button for serial number
public PageReference saveSerialIdNumber(){
    update Assets;
    update Cases;
    Assets = [SELECT id,Child_Fulfillment_Ticket__r.Equipment_Has_Been_Pulled__c,Serial_Number_Procurement__c,Name,Delivery_Address__c,Product_Code_Display__c,Product_Description_Display__c FROM Asset WHERE Serialized__c = true AND Child_Fulfillment_Ticket__c = :Cases.id]; 
    Cases = [SELECT id,Equipment_Has_Been_Pulled__c FROM Case WHERE id=: c.id];
    return null;
}
1
  • Adding Immediate="true" seems to break the button. When I add this, update a serial number on the visualforce page, check the Equipment_Has_Been_Pulled_c checkbox and click the save button none of the values are updated
    – Ian
    Jun 8 '20 at 21:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.