Wednesday, December 28, 2011

easy double-click to edit related-list VF page

Often enough I am asked to make a custom VisualForce of a related list that is editable in a similar way to salesforce's native double click to edit. I have made them in a variety of ways, including adding images like salesforce's to indicate if a field is editable or locked etc. and some simpler ways like the one I am going to do now.

The Problem:
a sObject under Account(or any other obj) needs show on the Account page layout, but it also needs to be double-click to edit to make it easy for the reps to update key information on the fly without having to click into each sObject. (for this example we will use the Contact obj)

First we need to create a controller extension so that it can sit in the page layout of the Account obj, and even though we are showing the contact obj, the extension needs to point to account otherwise it wont show up as an available VisualForce page to add on the layout.

This is a standard controller extension setup, this allows the class to use the account id referenced in the URL when the page is accessed. Example page URL will be 'apex/ContactInLineEdit?id={!}'

Now we should add the Contact list to the class so we can access it on the page in a apex:repeat, when we add it to the class, we only need to get the list on load of the page, and then again when we update the fields.

On the page we will need to add the apex:form tag, along with an apex:outputpanel with an id so we can call it later in a rerender attribute on the update call. We will also add the CSS and jQuery files that will help us control the double-click to edit functionality. We then place the jQuery inside the outputpanel so when it rerenders it can reapply the jQuery to the page. I also prefer to use the jQuery.noConflict(); since I often run into issues with salesforce's JS conflicting with what I am trying to implement.

Now we need to add the apex:pagemessages so we can do error handling and we need to add the table for the apex:repeat to sit in. We will also add the apex:outputfiled's that will display in the related list on the page, we need to make sure that any field we reference here is also in the select query on the class.

Lets add in the loading icon for the update and a JS function to control it, and we should also add the edit fields to the table. To help control the conditional hiding and showing of the fields for the edit, we should add some div's with classes to reference in jQuery.

Lets add the double click functionality, first we need to add a class to the edit text in the action column  <span class="editLink">Edit</span> then we need to add a function so that everytime the nonEdit field (outputField) is double-clicked it will hide the outputField and show the inputField. We will also change the Edit text to Cancel and add a class to it so we know that row is in edit mode.

Now lets add the edit row/cancel row edits functionality, this will allow all editable fields in the row to be edited and if cancel is hit, it will undo all edits by retrieving the text from the hidden outputfield otherwise it will continue to show the updated text since we are just hiding and showing. We don't want to clear the fields cause that will potentially clear out the saved info if it gets saved by mistake. So by retrieving the info from the outputfield, we are able to set it back to what it was originally.

We will also need to update our edit action to use the new function, it will now look like this: <span class="editLink" onclick="EditMe(jQuery(this));">Edit</span>
At this point we need to make the update method and add it to the page, this will allow any edits made by the user to be saved, and then the list will rerender with the new information.

And that it, simple. I didn't add it here, but field validation could be added to ensure its a proper email or phone number etc. In the style i made so that fields that were editable when the mouse hovered over it, the cursor would change to a pointer like it would when the mouse hovers over a link. This way the user knows the field is editable instead of having to add an image that could bog down the page load.

Twitter: @SalesForceGirl  or Facebook