[UTIL] Forms AJAX rendering component

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-11-2013 10:14 AM
Hi all,
This is something I needed for some customization I'm performing in Share.It is in a very premature state, but perhaps is useful for others. It is a client-side utility component for dynamically render forms retrieved to the forms component (/share/service/components/form) via AJAX requests. I'm not a JavaScrip guru so I'm open to any possible improvement/suggestion/bug fix. There you go:
A form can be easily initialized as follows:
Hope it helps.
Regards.
This is something I needed for some customization I'm performing in Share.It is in a very premature state, but perhaps is useful for others. It is a client-side utility component for dynamically render forms retrieved to the forms component (/share/service/components/form) via AJAX requests. I'm not a JavaScrip guru so I'm open to any possible improvement/suggestion/bug fix. There you go:
/** * Client-side JavaScript library. */// Defines root namespaceif (typeof MyCustom == undefined || !MyCustom) { var MyCustom = {};}// Defines top-level "custom" namespace, which will contain customization or extensions of existing components or objects in AlfrescoMyCustom.custom = MyCustom.custom || {};// Defines top-level "util" namespaceMyCustom.util = MyCustom.util || {};/** * Renderization and submission of forms generated by Forms Engine via Ajax requests. * * To know more about forms engine, invocation parameters and behavior: http://wiki.alfresco.com/wiki/Forms_Developer_Guide * * @class MyCustom.util.AjaxFormUI */(function(){ var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event; MyCustom.util.AjaxFormUI = function(htmlId, components) { components = YAHOO.lang.isArray(components) ? components : []; return MyCustom.util.AjaxFormUI.superclass.constructor.call( this, "MyCustom.util.AjaxFormUI", htmlId, components); }; YAHOO.extend(MyCustom.util.AjaxFormUI, Alfresco.component.Base, { /** * The default render config used by method render() * * @property options * @type object */ options: { itemId : null, mode : null, htmlid : null, container : null, successCallback : null, successMessage : null, failureMessage : null, cancelCallback : null }, /** * Reference to the DOM element which wraps up the form * * @property formWrapper * @type HTMLElement */ formWrapper: null, /** * Retrieves and renders the form by performing a request to the forms engine according * to the configuration object provided. * * @method renderForm * @param config {object} Description of the form to be generated * The config object has the following form: * { * itemId : {string}, // The identifier of the item the form is for, this will be different for each "kind" of item, for "node" it will be a NodeRef. * mode : {string}, // The mode the form will be rendered in, valid values are "view", "edit" and "create". * htmlid : {string}, // The htmlid of the current Surf component * container : {HTMLElement|string}, // Where the form will be allocated * successCallback : {Object} // A callback object literal used on form submission success * successMessage : {String} // A submit success message * failureMessage : {String} // A submit failure message * cancelCallback : {String} // A callback object literal used when form's cancel button is pressed * } */ render: function() { // TODO: to check mandatory options/parameters // Perform AJAX request to get form content from Forms Engine Alfresco.util.Ajax.request({ url: Alfresco.constants.URL_SERVICECONTEXT + "components/form", dataObj: { htmlid: this.options.htmlid, // Ensure unique IDs itemKind : "node", // It is fixed at the moment but could be dynamic in the future itemId : this.options.itemId, mode: this.options.mode, submitType: "json", formUI: true, showCancelButton: true }, successCallback : { fn : function(response) { // Create form wrapper where the form content is going to be inserted this.formWrapper = document.createElement("div"); this.formWrapper.setAttribute("id", this.options.htmlid + "-form-wrapper"); // Set appropriate id attribute this.formWrapper.setAttribute("class", "share-form"); // Set appropriate class // Fill the wrapper with the form component returned by the XHR request into this.formWrapper.innerHTML = response.serverResponse.responseText; // Append form wrapper to container element Dom.get(this.options.container).appendChild(this.formWrapper); }, scope : this }, failureMessage : Alfresco.util.message("message.failure"), // Generic failure message scope: this, execScripts: true // Automatically executes script tags (<script>) returned in the forms engine's response }); // Adjust form to work in dialog YAHOO.Bubbling.on("formContentReady", this._onFormContentReady, this); // When form is submitted make sure we hide the dialog after a successful submit and display a message when it fails. YAHOO.Bubbling.on("beforeFormRuntimeInit", this._onBeforeFormRunTimeInit, this); }, /** * * * @method _onFormContentReady * @param layer * @param args * @private */ _onFormContentReady: function(layer, args) { if (Alfresco.util.hasEventInterest(this.options.htmlid + "-form", args)) { // Close dialog when cancel button is clicked var cancelButton = args[1].buttons.cancel; // Destroy the form when cancel button is clicked, by default cancelButton.addListener("click", this._destroy, this, true); // Execute custom function on button click if the object that describes it exists if (this.options.cancelCallback && YAHOO.lang.isFunction(this.options.cancelCallback.fn)) { cancelButton.addListener( "click", // Event triggered this.options.cancelCallback.fn, // Function executed this.options.cancelCallback.scope || {}, // Scope true); // The custom object that is passed is used for the execution scope (so it becomes "this" in the callback) } } }, /** * * * @method _onBeforeFormRunTimeInit * @param layer * @param args * @private */ _onBeforeFormRunTimeInit: function(layer, args) { if (Alfresco.util.hasEventInterest(this.options.htmlid + "-form", args)) { args[1].runtime.setAJAXSubmit(true, { successCallback : { fn : function PopupMananger_displayForm_formSuccess(response) { // Destroy the form wrapper and its content this.options.container.removeChild(this.formWrapper); // Invoke success if (this.options.successCallback && YAHOO.lang.isFunction(this.options.successCallback.fn)) { // TODO: does the callback function really needs to receive arguments?? this.options.successCallback.fn.call(this.options.successCallback.scope || {}, response, this.options.successCallback.obj) } }, scope : this }, successMessage : this.options.successMessage, failureMessage : this.options.failureMessage }); } }, /** * Implements self-destruction of the component * * @method _destroy * @param event * @param obj * @private */ _destroy: function(event, obj) { // Remove the form wrapper from the DOM obj.options.container.removeChild(Dom.get(obj.formWrapper)); // Form destruction signal YAHOO.Bubbling.fire("formContainerDestroyed"); // Unsubscribe events YAHOO.Bubbling.unsubscribe("beforeFormRuntimeInit", this._onBeforeFormRunTimeInit, obj); YAHOO.Bubbling.unsubscribe("formContentReady", this._onFormContentReady, obj); // Clean instance attributes delete this.formWrapper; // Invoke super (Alfresco.component.Base) destroy method this.destroy(); }, });})();
A form can be easily initialized as follows:
var form = new MyCustom.util.AjaxFormUI(); form.setOptions( { itemId : "workspace://SpacesStore/73ddea6e-c937-4db3-af65-44c82150a72f", mode : "edit", htmlid : parent.id, container : Dom.get(parent.id + "-container"), successCallback: { fn: parent.onCreateUserFormCancelClick, scope: parent }, successMessage : parent._msg("message.update-success"), cancelCallback: { fn: parent.onCreateUserFormCancelClick, scope: parent } }); form.render();
Hope it helps.
Regards.
Labels:
- Labels:
-
Archive
6 REPLIES 6

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-12-2013 10:36 AM
Forgot to post a usage example


Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-07-2013 05:40 PM
This looks excellent. I stumbled across your post looking for something else, found my answer in your code. Although I won't be using the code myself, this looks very neat for the future uses


Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-13-2013 04:10 AM
I'm glad you found it useful 
The component has changed slightly in the mean time, let me know if you want me to post it. Some feedback in terms of improvements would be appreciated as well.
Ragards.

The component has changed slightly in the mean time, let me know if you want me to post it. Some feedback in terms of improvements would be appreciated as well.
Ragards.
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-19-2013 07:25 AM
Useful post!!! helped me… Thanks!

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-19-2013 09:11 AM
Glad to know it Paiyyavj13. If you come up with any improvement or you find issues, please share with us!
Cheers.
Cheers.

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-20-2015 01:48 AM
thank you for this post !
It helped me solve many issues in my code
It helped me solve many issues in my code

