This article is relevant if you want to get control over the HTML to be crafted by business users held within NetSuite rich text fields.
Background
We have a client in the advertising media industry that has an elaborate business coordination between their customers and suppliers. The coordination demands that a contract is placed for each customer / supplier working relationship. The contract will be executed via our advanced use of the Adobe Sign (formerly EchoSign) electronic signature platform. Elements of the contract language require business staff to refine standard contract language elements as they work to produce the engagement.
We make extensive use of NetSuite’s Advanced PDF technology for our clients. Most all of our clients leverage our Content Renderer Engine (CRE) to get to hard to reach data elements to produce high quality branded documents. Using the technology, we were able to embed additional tokens into the contract template that can act as placeholders for the individual contract language elements that are edited by the staff. Many times, content elements were cut-and-pasted from Microsoft Word. Yet, we found that NetSuite’s native Rich Text HTML editor produced malformed HTML (especially around indented lists) that would break the final PDF compilation.
After hacking away at the challenge, we realized that if we replace NetSuite’s HTML editor, we open the possibility to get control over the generated HTML at the source. No more hacking; just clean HTML.
How to Add a Custom HTML Editor to NetSuite
After working with a couple of different browser based html editors, we landed on the open source TinyMCE editor. This editor is popular in the larger web community and is lightweight and fast. Working with one of my senior consultants, we were able to succeed with the following implementation pattern:
- Dynamically add a new Text based field to the form.
- Hide NetSuite’s native Rich Text Format field.
- Plug in TinyMCE to take over the Text based field.
- Upon record save, replace the native Rich Text Format field with the value of TinyMCE edited Text based field.
Here are the code snippets to help your implementation:
User Event Before Load
//NOTE: fieldname contains the name of the “native” RTF field to replace with tinyMCE var fieldName = “custbody_sample_field”; var nativeField = context.form.getField(fieldName); var fld = context.form.addField({ id: fieldName.replace("custbody_","custpage_"), label: nativeField.label, type: serverWidget.FieldType.LONGTEXT }); fld.defaultValue = REC.getValue(fieldName); nativeField.updateDisplayType({displayType: serverWidget.FieldDisplayType.HIDDEN});
Client Page Init
// load the tinyMCE library var d = document; var sc2=d.createElement('script'); sc2.src = “https://cloud.tinymce.com/stable/tinymce.min.js”; d.getElementsByTagName('*')[1].appendChild(sc2); // unfortunately, the above happens asynchronously, so we need a mechanism for waiting until the library is loaded/processed // before we can begin using it; we use JavaScript’s setInterval() method, executing it every 10 milliseconds until we have success // and then clear it var fieldname = “custbody_sample_field”; var t = setInterval(function() { try { if (tinymce) { clearInterval(t); // initialize tinymce and tell it to target an existing text field tinymce.init({selector: "textarea#" + fieldName.replace("custbody_","custpage_"), branding: false, resize: 'both', width: 600, height: 300, menubar: false, plugins: "textcolor lists" }); } } catch (e1) { ; } },10);
Client Page Save
// extract the contents from the tinyMCE editor and put it back into our temp text field var fieldname = “custbody_sample_field”; context.currentRecord.setValue(fieldName.replace("custbody_","custpage_"),tinymce.editors[fieldName.replace("custbody_","custpage_")].getContent());
User Event Before Submit
// take the data from the custom/temp field, and put it back into the native field var fieldname = “custbody_sample_field”; context.newRecord.setValue(fieldName,context.newRecord.getValue(fieldName.replace("custbody_","custpage_")));
Invent on the NetSuite Platform
This article is a great example of how our team innovates on the NetSuite platform. By having a strong fundamental NetSuite understanding both for the native capacities and the platform, we are poised to design solutions that otherwise may appear impossible. To invent solutions demands the capacity to envision the future and possess the actual tactics to build toward that end. We welcome working with professionals that have grown their skills for that talent. Perhaps you would like to work with a team of high caliber professionals? If so, let’s have a conversation.