function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
BDArnzBDArnz 

Show/Hide save/cancel buttons with in-line edit on a nested table.

In short, my need is to make buttons show/hide when in-line editing is open on a record inside a table on a VF page. 

 

this code:

 

<apex:inlineEditSupport event="ondblClick" showonEdit="saveButton,cancelButton" />

 Works beautifully when the save and cancel buttons are in the <pageBlockButtons> tag.

 

My model is a little complex however.  I have 3 custom objects A, B & C.  A is related to multiple records in B.  And each record in B is related to multiple records in C.  (All normal lookup relationships).  SF standard UI page would have Detail A & related list B on a single page.  Detail B would have related list C on a single page.  I would like to have A, B & C all on the same page.  It was a pretty short VF leap to connect C back to A and create a page:  Detail A, related list B and related list C on the single VF page.  The problem is that it's not easy to connect which records C connect to which records B.  Got it?

 

I did some digging and figured out how to create nested tables.  So now I have Detail A, then my table which has B1 followed by all of it's related Cs then B2 followed by it's related Cs, etc through all of the records B.  This looks great.  I can now see A, B and C and it's easy to see which Cs belong to which Bs all on a single VF page.  I needed a couple of wrapper classes in the controller.

 

NOW I want to enable in-line editing inside this table so each record (whether it's a B or a C) can be edited directly from this single page rather than have to jump over to the respective detail pages and then have to find my way back.  in-line editing is cool.  It worked when my table only had Bs or Cs.  In those cases having the buttons in their respective <pageBlockButton> tag worked well.

 

Here's the page markup:

<apex:page Title="Seven Step"
	StandardController="X7_Step__c" 
	Extensions="SevenStepEXT" 
	TabStyle="X7_Step__c">

	<apex:form >
		
		<apex:detail subject="{!this7Step.Id}" relatedList="false" title="true" id="X7StepDetail" inlineEdit="true"/>


    	<b>Step 3 Potential Root Causes and Analysis</b>
    	<apex:pageBlock >
			<apex:repeat value="{!wrapout}" var="w">
					<table 
						border="3"
						cellpadding="3"
						id="table">
						<tr>
							<td style="width:150px">
								<b>Rating:&nbsp;&nbsp;</b>
       							<apex:outputField value="{!w.Cause.Rating__c}">
       								<apex:inlineEditSupport event="ondblClick"/>
       							</apex:outputField>
							</td>
							<td style="width:400px">
								<b>Possible Cause:&nbsp;&nbsp;</b>
								<apex:outputField value="  {!w.Cause.Name}">
									<apex:inlineEditSupport event="ondblClick" showonEdit="saveButton,cancelButton"/>
								</apex:outputField>
							</td>
							<td rowspan="2">
								<apex:commandButton action="{!w.SaveCause}" id="saveButton" value="Save"  style="display: none;"/>
								<apex:commandButton onclick="resetInlineEdit()" id="cancelButton" value="Cancel"  style="display: none;"/>
							</td>
						</tr>
						<tr>
							<td colspan="2" style="width:550px">
								<b>Detail:&nbsp;&nbsp;</b>
       							<apex:outputField value="{!w.Cause.Root_Cause__c}">
       								<apex:inlineEditSupport event="ondblClick"/>
       							</apex:outputField>
							
							</td>
						</tr>
					</table>
					
					
            	<apex:pageBlockTable value="{!w.steps}" var="wo">
            		<apex:column >
            			<apex:outputField value="{!wo.step.Step__c}"/>
            		</apex:column>
             		<apex:column >
            			<apex:outputField value="{!wo.step.Result__c}"/>
            		</apex:column>
            	</apex:pageBlockTable>
            	<hr/>
			</apex:repeat>        	
    	</apex:pageBlock>
	</apex:form>
</apex:page>	

 And the controller extension:

public with sharing class SevenStepEXT {
	Public X7_Step__c this7Step {get;set;}
	Private List<Root_Cause__c> Causes = new List<Root_Cause__c>();
	Private Map<ID,List<Testing_Steps__c>> CauseStepMAP = new Map<Id,List<Testing_Steps__c>>();	
	Private Set<ID> CauseIDs = new Set<ID>();
    public List<wrapper> wrapout {get; set;}
	

    Public SevenStepEXT (ApexPages.StandardController stdController) {
        this7Step = (X7_Step__c)stdController.getRecord();
        wrapout = new List<wrapper>();

        Causes = [select Id,
        			Name,
        			Case__c,
        			Cause__c,
        			Rating__c,
        			Root_Cause__c,
        			X7_Step__c 
        			from Root_Cause__c 
        			where X7_Step__c = :this7Step.id AND IsDeleted = false];
        for(Root_Cause__c rc:Causes){CauseIDs.add(rc.id);}
        for(Testing_Steps__c ts:[select Id,
        							Name,
        							Case__c,
        							Result__c,
        							Root_Cause__c,
        							Step__c,
        							X7_Step__c 
        							from Testing_Steps__c 
        							where Root_Cause__c=:CauseIDs AND IsDeleted = false]){
            if(CauseStepMAP.containsKey(ts.Root_Cause__c)){
                CauseStepMAP.get(ts.Root_Cause__c).add(ts);//adds Test Step for this Cause to the Test Step list in the map    
            }else{
                CauseStepMAP.put(ts.Root_Cause__c,new List<Testing_Steps__c>{ts});//adds new Test Step list for this Cause to the map    
            }
        }

        for(Root_Cause__c c:Causes){
            wrapper tmpwrapper = new wrapper();
            tmpwrapper.Cause=c;
            List<wrapper2> t2 = new List<wrapper2>();
            for(Testing_Steps__c s:CauseStepMAP.get(c.id)){
                wrapper2 twrap2 = new wrapper2();

                twrap2.Step=s;
                t2.add(twrap2);
            }
            tmpwrapper.Steps=t2;
            wrapout.add(tmpwrapper);
        }
    }


    //wrapper 1
    class wrapper{
    	Public Boolean ShowButtons {get;set;}
        public Root_Cause__c Cause {get; set;}
        //This is a list of other wrappers that is nested in the first list        
        public List<wrapper2> Steps {get; set;}
        public wrapper(){
            if(Cause==null){Cause = new Root_Cause__c();}//initialize the Cause holder
            if(Steps==null){Steps = new List<wrapper2>();}//initialize the Steps listholder
        	ShowButtons = false;
        }
    
	    Public void SaveCause(){
	    	Update Cause;
	    }
    	
    	Public void toggleButtons(){
    		if (ShowButtons == true){
    			ShowButtons = false;
    		}else{
    			ShowButtons = true;
    		}
    	}
    
    }





    //wrapper 2 - the Test Steps
    class wrapper2{
        Public Testing_Steps__c Step {get; set;}
        public wrapper2(){
            if(Step==null){Step = new Testing_Steps__c();}//initialize the Testing_Step__c holder
        }
    }

 

 

The table renders perfectly (it still needs some formatting...) and the in-line edit mode enables when doubleclicking the fields.  The buttons do work properly when they're visible.  Save saves the individual specific record and cancel aborts.  The problem is that I DON'T want them visible until in-line edit is enabled. and I want them to go away after saving.  I can't make the buttons work in the <pageBlockButton> tag because the save is not in context with the record so it made sense to have the buttons appear in a cell in the same row as the record and have the save method in the appropriate wrapper class.  Everything is in context and everything saves.  How do I make them come and go?

 

I have tried using a render boolean value but I don't know how to trigger a method in the controller to switch the value upon in-line edit mode and I can't get that even to rerender...

 

Anyone have any ideas on this?