This document explains the way to enhance a Display field in Form Widget to be able to use Ajax.InPlaceEditor. Refer to the following JIRA issue for the implementation progress of this enhancement: OFBIZ-1859. The initial code for this enhancement is checked in and the patch for improvements is posted on the same issue.
In Form Widget a display field is used to render any non-editable content. The text is usually rendered in a span (td if no widget-style is applied). We can use id attribute with the span tag. Our goal is to use Ajax.InPlaceEditor for a display field in form widget so that we can in place edit by clicking on any non-editable content rendered in our view.
Ajax.InPlaceEditor allows the use to edit a non-editable content by simply clicking on it. This turns the static element into an editable zone (either single-line or multi-line), and pops up submit and cancel buttons to allow user to commit or rollback the modification. It then synchronizes the edit on the server-side through AJAX, and makes the element non-editable again. There can be three types of in place editions of a non-editable content:
Current implementation is focused on to provide single/multi line edit feature in a display field of Form Widget.
Here is the implementation for this particular enhancement.
Added a new sub element <in-place-editor> and define following attributes with default values set for some of the attributes. These attributes allows the developer to set the options that are passed to Ajax.InPlaceEditor function.
Sub-elements of <in-place-editor>:
Defined a new class org.ofbiz.widget.form.ModelFormField.InPlaceEditor which will get attributes of <in-place-editor> element and set their values. It also handles the sub elements as well. Defined required methods and a constructor for the same.
Defined a new variable of org.ofbiz.widget.form.ModelFormField.InPlaceEditor class in org.ofbiz.widget.form.ModelFormField.DisplayField class. Added code in the constructor of org.ofbiz.widget.form.ModelFormField.DisplayField class to parse the <auto-complete-options> element and if found instantiate org.ofbiz.widget.form.ModelFormField.InPlaceEditor class.
Defined methods in org.ofbiz.widget.form.ModelFormField.DisplayField class to get and set (instantiate) object of org.ofbiz.widget.form.ModelFormField.InPlaceEditor class.
Instantiated the object of org.ofbiz.widget.form.ModelFormField.InPlaceEditor class using org.ofbiz.widget.form.ModelFormField.DisplayField.getInPlaceEditor() method. If this object is not null and JavaScript is enabled in the request, set a boolean ajaxEnabled equals true.
If ajaxEnabled is true, appended a <script> which prepares the urlString with fields in fieldMap passed as a query string in the url, calls the JavaScript function (ajaxInPlaceEditDisplayField()) defined in selectall.js, by passing the required parameters, i.e. elementId, url and a hash of options to this function.
Implemented a function ajaxInPlaceEditDisplayField() in selectall.js which takes elment, url and a hash of options as parameters and calls Ajax.InPlaceEditor passing all these parameters to it.
In the current implementation if htmlResponse is set to true(which is set as default) Ajax.Updater is called which updates the edited element with the responseText once the request call is complete. In OFBiz framework, first a service returns a response which contains many information, and second we cannot set every non-pk attribute as an out parameter in a service. So this blocks us from properly updating the edited element. On the other hand if htmlResponse is set to false Ajax.Request is called which on successful completion does not update the edited element with new value. We can now use Ajax.Request but we need it to update the edited element with new value. For this I introduced a new option in Ajax.InPlaceEditor named updateAfterRequestCall which if set to true updates the element with new value after Ajax.Request call is completed and if set to false sustains the original behavior. First we grab the value of the editor in the global variable paramValue in handleFormSubmission() function. Than an onSuccess callback function updateElement() is called in Ajax.Request, which, if updateAfterRequestCall is set to true, updates the element with paramValue.