+ Start a Discussion
Pasan   EeriyagamaPasan Eeriyagama 

Apex Metadata API Layout Read-only fields being added as Read-write

We have Layout Read-only fields to be added. Seems like a bug, when we try to add read-only fields they become read-write on layout. Please see below example.
 
public class metadatatest {
    public static void runUpdateLayouts(){        
        Metadata.Layout la = getLayout('Account-Account Layout');

        Metadata.LayoutSection sec = new Metadata.LayoutSection();
        sec.customLabel = true;
        sec.detailHeading = true;
        sec.editHeading = true;
        sec.label = 'Custom fields';
        sec.style = metadata.LayoutSectionStyle.OneColumn;

        Metadata.LayoutColumn col1 = new Metadata.LayoutColumn();

        Metadata.LayoutItem layoutField = new Metadata.LayoutItem();

        layoutField.field = 'testfield__c';
        layoutField.behavior = metadata.UiBehavior.Readonly;

        col1.layoutItems.add(layoutField);
        sec.layoutColumns.add(col1);

        la.layoutSections.add(sec);

        Metadata.DeployContainer dc = new Metadata.DeployContainer();
        dc.addMetadata(la);

        Id jobid = Metadata.Operations.enqueueDeployment(dc,null);
    }

    public static Metadata.Layout getLayout(String layoutName){
        List<String> layoutList = new List<String>{layoutName};
            List<Metadata.Metadata> components = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, layoutList);
        return (Metadata.Layout)components[0];
    }
}


Above code will add testfield__c field to Account standard layout. But it shows as Readonly in Layout editor. But in Account both view and edit modes it's read-write.

On Layout editor:
In Layout editor

On View/Edit mode:
Edit/View Mode

It's actually editable and saving data to Account object here. Feel free to try out above code snippet. Appreciate any fix/workaround for this. Thanks.

 
Best Answer chosen by Pasan Eeriyagama
NagendraNagendra (Salesforce Developers) 
Hi Pasan,

The "Edit read-only fields" permission is set to the System Administrator profile. Have you tested under a different profile that does not have that permission set? 

Please let us know for further clarification.

Thanks,
Nagendra

All Answers

NagendraNagendra (Salesforce Developers) 
Hi Pasan,

The "Edit read-only fields" permission is set to the System Administrator profile. Have you tested under a different profile that does not have that permission set? 

Please let us know for further clarification.

Thanks,
Nagendra
This was selected as the best answer
Amol Salve 13Amol Salve 13
Hello Pasan,

You need to check field level security for various profile 

Thanks
Amol Salve
Salesforce developer
Abdulla d 5Abdulla d 5
// to add custom fields to pageouts using meta data
public class UpdateContactPageLayout {
    public Metadata.Layout addLayoutItem() {
        
        // Retrieve Account layout and section 
        List<Metadata.Metadata> layoutsList  = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, 
            new List<String> {'Contact-Contact Layout'});
        Metadata.Layout layoutMetadata  = (Metadata.Layout) layoutsList.get(0);
        Metadata.LayoutSection contactLayoutSection = null;
        List<Metadata.LayoutSection> layoutSections = layoutMetadata.layoutSections;
        for (Metadata.LayoutSection section : layoutSections) {
            
            if (section.label == 'Additional Information') {
                contactLayoutSection = section;
                break;
            }
        }
        
        // Add the field under Account info section in the left column
        List<Metadata.LayoutColumn> contactColumns  = contactLayoutSection.layoutColumns;     
        List<Metadata.LayoutItem> contactLayoutItems  = contactColumns .get(0).layoutItems;
        
        // Create a new layout item for the custom field
        Metadata.LayoutItem newField  = new Metadata.LayoutItem();
        newField .behavior = Metadata.UiBehavior.Edit;
        newField .field = 'AMAPI__Apex_MD_API_Twitter_name__c';
        contactLayoutItems.add(newField);
        
        return layoutMetadata ;
    }
}
Nitin LedangeNitin Ledange
Below Code worked for me : 

public class UpdateContactPageLayout {
    public Metadata.Layout addLayoutItem (){
        List<Metadata.Metadata> layoutsList  = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, 
            new List<String> {'Contact-Contact Layout'});
        Metadata.Layout layoutMetadata = (Metadata.Layout) layoutsList.get(0);
        
        Metadata.LayoutSection contactLayoutSection  = null;
        
        for(Metadata.LayoutSection section : layoutMetadata.LayoutSections){
            if(section.label == 'Additional Information'){
               contactLayoutSection = section; 
                break;
            }
        }
        
        List<Metadata.LayoutColumn> contactColumns =  contactLayoutSection.layoutColumns ;
        List<Metadata.LayoutItem> contactLayoutItems  = contactColumns.get(0).layoutItems ;
        
        Metadata.LayoutItem newField  = new Metadata.LayoutItem();
        newField.behavior = Metadata.UiBehavior.Edit;
        newField.field = 'AMAPI__Apex_MD_API_Twitter_name__c';
        contactLayoutItems.add(newField);
        
        return layoutMetadata;
    }
}