You need to sign in to do that
Don't have an account?
Eric Santiago
WYSIWYG Editors for textarea fields
I've been experimenting with adding TinyMCE (http://tinymce.moxiecode.com/) to Sforce controls to add HTML formatting features to textareas in Salesforce.
Originally, I planned to add a pop-up window to the edit screen for my custom object and have the formatted text sent back to the parent window. Unfortunately, unless I'm mistaken, you can't add scontrols to the edit screen.
It seems then that the only option is to override the edit button. Ideally I'd like to run the TinyMCE javascript (see below) as the edit screen loads. Is there a way to do this?
Code:
If that's also not an option, I was thinking about using a Scontrol that ran the tinyMCE code and then took advantage of the DescribeLayoutResult call to build the normal edit page layout. Using a dynamic rather than static page layout seemed the best way to reuse the WYSIWYG editor for any number of custom objects. Unfortunately, I haven't seen anu ajax samples using this call and developing it from scratch is far beyond my own expertise. Perhaps some ingenious soul is willing to take on the challenge?
Originally, I planned to add a pop-up window to the edit screen for my custom object and have the formatted text sent back to the parent window. Unfortunately, unless I'm mistaken, you can't add scontrols to the edit screen.
It seems then that the only option is to override the edit button. Ideally I'd like to run the TinyMCE javascript (see below) as the edit screen loads. Is there a way to do this?
Code:
<script type="text/javascript" src="http://wiki.moxiecode.com/examples/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script language="javascript" type="text/javascript">
tinyMCE.init({
mode : "textareas",
theme : "advanced",
plugins : "table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,zoom,flash,searchreplace,print,contextmenu",
theme_advanced_buttons1_add_before : "save,separator",
theme_advanced_buttons1_add : "fontselect,fontsizeselect",
theme_advanced_buttons2_add : "separator,insertdate,inserttime,preview,zoom,separator,forecolor,backcolor",
theme_advanced_buttons2_add_before: "cut,copy,paste,separator,search,replace,separator",
theme_advanced_buttons3_add_before : "tablecontrols,separator",
theme_advanced_buttons3_add : "emotions,iespell,flash,advhr,separator,print",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_path_location : "bottom",
plugin_insertdate_dateFormat : "%Y-%m-%d",
plugin_insertdate_timeFormat : "%H:%M:%S",
extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
external_link_list_url : "example_data/example_link_list.js",
external_image_list_url : "example_data/example_image_list.js",
flash_external_list_url : "example_data/example_flash_list.js"
});
</script>
If that's also not an option, I was thinking about using a Scontrol that ran the tinyMCE code and then took advantage of the DescribeLayoutResult call to build the normal edit page layout. Using a dynamic rather than static page layout seemed the best way to reuse the WYSIWYG editor for any number of custom objects. Unfortunately, I haven't seen anu ajax samples using this call and developing it from scratch is far beyond my own expertise. Perhaps some ingenious soul is willing to take on the challenge?
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><title>Scorecard Task Edit: New Scorecard Task ~ Salesforce - Enterprise Edition</title><link href="/sCSS/8.0/1171411121000/Theme2/default/elements.css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet" type="text/css" /><link href="/sCSS/8.0/1171411121000/Theme2/default/common.css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet" type="text/css" /><link href="/css/assistive.css" media="aural,braille,embossed" rel="stylesheet" type="text/css" /><link href="/sCSS/8.0/1172004110000/Theme2/00D300000000dDf/00530000000f5K2/dCustom.css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://wiki.moxiecode.com/examples/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script language="javascript" type="text/javascript">
tinyMCE.init({
mode : "textareas",
theme : "advanced",
plugins : "table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,zoom,flash,searchreplace,print,contextmenu",
theme_advanced_buttons1_add_before : "save,separator",
theme_advanced_buttons1_add : "fontselect,fontsizeselect",
theme_advanced_buttons2_add : "separator,insertdate,inserttime,preview,zoom,separator,forecolor,backcolor",
theme_advanced_buttons2_add_before: "cut,copy,paste,separator,search,replace,separator",
theme_advanced_buttons3_add_before : "tablecontrols,separator",
theme_advanced_buttons3_add : "emotions,iespell,flash,advhr,separator,print",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_path_location : "bottom",
plugin_insertdate_dateFormat : "%Y-%m-%d",
plugin_insertdate_timeFormat : "%H:%M:%S",
extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
external_link_list_url : "example_data/example_link_list.js",
external_image_list_url : "example_data/example_image_list.js",
flash_external_list_url : "example_data/example_flash_list.js"
});
</script>
<script type="text/javascript" src="/js/functions.js"></script>
<script src="/dJS/en/1170289429000/library.js" type="text/javascript"></script><script type="text/javascript" src="/js/setup.js"></script>
<script type="text/javascript" src="/js/roletreenode.js"></script>
<script type="text/javascript" src="/desktop/desktopAjax.js"></script>
<script type="text/javascript">window.sfdcPage = new EditPage();</script><link rel="shortcut icon" href="https://na1.salesforce.com/favicon.ico" />
</head><body onLoad="if (this.bodyOnLoad) bodyOnLoad();" onBeforeUnload="if (this.bodyOnBeforeUnload) bodyOnBeforeUnload();" onUnload="if (this.bodyOnUnload) bodyOnUnload();" onResize="if (this.bodyOnUnload) bodyOnUnload();" onFocus="if (this.bodyOnFocus) bodyOnFocus();" class="custom customTab35 editPage"><iframe title="blank - ignore" name="div_submit" id="div_submit" src="/s.gif" style="display:none;visibility:hidden;width:0px;height:0px" frameborder="0"></iframe>
<!-- Main Body Starts Here -->
<!-- <table class="outer" width="100%" id="bodyTable" border="0" cellspacing="0" cellpadding="0"> -->
<table width="100%" id="bodyTable" border="0" cellspacing="0" cellpadding="0">
<!-- Start page content table -->
<tr><td class="oRight" id="bodyCell">
<!-- Start page content -->
<a name="skiplink"><img src="/s.gif" height='1' width='1' alt="Content Starts Here" class="skiplink" title="Content Starts Here"></a><div class="bPageTitle"><div class="ptBody secondaryPalette"><div class="content"><img src="/s.gif" alt="Scorecard Task" class="pageTitleIcon" title="Scorecard Task"><h1 class="pageType">Scorecard Task Edit<span class="titleSeparatingColon">:</span></h1><h2 class="pageDescription"> New Scorecard Task</h2><div class="blank"> </div></div><div class="links"><a href="javascript:openPopupFocusEscapePounds('/help/doc/user_ed.jsp—loc=help&target=co_edit.htm§ion=CustomObjects', 'Help', 700, 600, 'width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no', false, false);" title="Help for this Page (New Window)"><span class="helpLink">Help for this Page</span><img src="/s.gif" alt="" class="helpImage" title=""></a></div></div><div class="ptBreadcrumb"></div></div><script type="text/javascript">
</script>
<script src="/js/picklist.js" type="text/javascript"></script><script src="/servlet/servlet.picklist–h=v8dt%2FM%2FqeljSZznkR%2BGou%2FgVozUMdUIEJHxLCUIJ5Pg%3D&v=1141632834000&layout=00h300000011UVZ&l=0&pr=1.23&t=0" type="text/javascript"></script><form action="/a0D/e" id="editPage" method="post" name="editPage" onsubmit="if (window.ffInAlert) { return false; }" ><input type="hidden" name="cancelURL" id="cancelURL" value="/a0D/o" /><input type="hidden" name="retURL" id="retURL" value="/a0D/o" /><input type="hidden" name="save_new_url" id="save_new_url" value="/a0D/e˜retURL=%2Fa0D%2Fo" /><div class="bPageBlock bEditBlock secondaryPalette" id="ep"><div class="pbHeader"><table border="0" cellpadding="0" cellspacing="0"><tr><td class="pbTitle"><img src="/s.gif" alt="" width="1" height="1" class="minWidth" title="" /><h2 class="mainTitle">Scorecard Task Edit</h2></td><td class="pbButton"><input value=" Save " class="btn" type="submit" title="Save" name="save" /> <input value="Save & New" class="btn" type="submit" title="Save & New" name="save_new" /> <input value="Cancel" class="btn" type="submit" title="Cancel" name="cancel" /></td></tr>
</table></div><div class="pbBody"><div class="pbSubheader first tertiaryPalette" id="head_1_ep"><span class="pbSubExtra"><span class="requiredLegend"><span class="requiredExampleOuter"><span class="requiredExample"> </span></span><span class="requiredText"> = Required Information</span></span></span><h3>Information<span class="titleSeparatingColon">:</span></h3></div><div class="pbSubsection"><table class="detailList" border="0" cellpadding="0" cellspacing="0"><tr><td class="labelCol requiredInput"><label for="Name"><span class="requiredMark">*</span>Task Label</label></td><td class="dataCol col02"><div class="requiredInput"><div class="requiredBlock"></div><input id="Name" maxlength="80" name="Name" size="20" tabindex="1" type="text" /></div></td><td class="labelCol">Owner</td><td class="dataCol">Eric Santiago</td></tr>
<tr><td class="labelCol"><label for="00N3000000160GA">Active™</label></td><td class="dataCol col02"><input id="00N3000000160GA" name="00N3000000160GA" tabindex="2" type="checkbox" value="1" /></td><td class="labelCol"><label for="00N3000000160GK">Rank</label></td><td class="dataCol"><input id="00N3000000160GK" name="00N3000000160GK" size="20" tabindex="5" type="text" /></td></tr>
<tr><td class="labelCol"><label for="00N3000000160Fg">Category</label></td><td class="dataCol col02"><span><select id="00N3000000160Fg" name="00N3000000160Fg" tabindex="3">
<option value="" selected>--None--</option>
</select></span><script>new picklist('00N3000000160Fg','00N3000000160Fg',null,['',''],' id="00N3000000160Fg" name="00N3000000160Fg" tabindex="3"',true,true);</script>
</td><td class="labelCol"><label for="00N3000000160Fq">Subcategory</label></td><td class="dataCol"><span><select id="00N3000000160Fq" name="00N3000000160Fq" tabindex="6">
<option value="" selected>--None--</option>
</select></span><script>new picklist('00N3000000160Fq','00N3000000160Fq',null,['',''],' id="00N3000000160Fq" name="00N3000000160Fq" tabindex="6"',true,true);</script>
</td></tr>
<tr><td class="labelCol requiredInput last"><label for="00N3000000160FD"><span class="requiredMark">*</span>Type</label></td><td class="dataCol col02 last"><div class="requiredInput"><div class="requiredBlock"></div><span><select id="00N3000000160FD" name="00N3000000160FD" tabindex="4">
<option value="" selected>--None--</option>
</select></span><script>new picklist('00N3000000160FD','00N3000000160FD',null,['',''],' id="00N3000000160FD" name="00N3000000160FD" tabindex="4"',false,true);</script>
</div></td><td class="labelCol last"><label for="00N3000000162II">Archive?</label></td><td class="dataCol last"><input id="00N3000000162II" name="00N3000000162II" tabindex="7" type="checkbox" value="1" /></td></tr>
</table></div><div class="pbSubheader tertiaryPalette" id="head_2_ep"><h3>Program & Year<span class="titleSeparatingColon">:</span></h3></div><div class="pbSubsection"><table class="detailList" border="0" cellpadding="0" cellspacing="0"><tr><td class="labelCol"><label for="00N300000016Car"><font color=red>Note 2:</label></td><td class="data2Col" colspan="3"><span><select id="00N300000016Car" name="00N300000016Car" tabindex="8">
<option value="Academic Year is valid only for 4XL Program." selected>Academic Year is valid only for 4XL Program.</option>
</select></span><script>new picklist('00N300000016Car','00N300000016Car',null,['Academic Year is valid only for 4XL Program.','Academic Year is valid only for 4XL Program.'],' id="00N300000016Car" name="00N300000016Car" tabindex="8"',true,true);</script>
</td></tr>
<tr><td class="labelCol requiredInput"><label for="CF00N300000016Cdp"><span class="requiredMark">*</span>MLT Program</label></td><td class="data2Col" colspan="3"><div class="requiredInput"><div class="requiredBlock"></div><input type="hidden" name="CF00N300000016Cdp_lkid" id="CF00N300000016Cdp_lkid" value="000000000000000" /><input type="hidden" name="CF00N300000016Cdp_lkold" id="CF00N300000016Cdp_lkold" value="null" /><input type="hidden" name="CF00N300000016Cdp_lktp" id="CF00N300000016Cdp_lktp" value="a0C" /><input type="hidden" name="CF00N300000016Cdp_lspf" id="CF00N300000016Cdp_lspf" value="0" /><input type="hidden" name="CF00N300000016Cdp_mod" id="CF00N300000016Cdp_mod" value="0" /><span class="lookupInput"><input id="CF00N300000016Cdp" maxlength="80" name="CF00N300000016Cdp" onchange="document.getElementById('CF00N300000016Cdp_lkid').value='';document.getElementById('CF00N300000016Cdp_mod').value='1';" size="75" tabindex="9" type="text" /><a href="JavaScript: openLookup('/_ui/common/data/LookupPage?lkfm=editPage&lknm=CF00N300000016Cdp&lktp=' + document.getElementById('CF00N300000016Cdp_lktp').value,670,document.getElementById('CF00N300000016Cdp_mod').value,'&lksrch=' + escapeUTF(document.getElementById('CF00N300000016Cdp').value),'maxw')" id="CF00N300000016Cdp_lkwgt" onclick="setLastMousePosition(event)" tabindex="9" title="MLT Program Lookup (New Window)"><img src="/s.gif" alt="MLT Program Lookup (New Window)" class="lookupPopup" title="MLT Program Lookup (New Window)"></a></span></div></td></tr>
<tr><td class="labelCol"><label for="CF00N3000000160HS">Academic Year</label></td><td class="data2Col" colspan="3"><input type="hidden" name="CF00N3000000160HS_lkid" id="CF00N3000000160HS_lkid" value="000000000000000" /><input type="hidden" name="CF00N3000000160HS_lkold" id="CF00N3000000160HS_lkold" value="null" /><input type="hidden" name="CF00N3000000160HS_lktp" id="CF00N3000000160HS_lktp" value="a0G" /><input type="hidden" name="CF00N3000000160HS_lspf" id="CF00N3000000160HS_lspf" value="0" /><input type="hidden" name="CF00N3000000160HS_mod" id="CF00N3000000160HS_mod" value="0" /><span class="lookupInput"><input id="CF00N3000000160HS" maxlength="80" name="CF00N3000000160HS" onchange="document.getElementById('CF00N3000000160HS_lkid').value='';document.getElementById('CF00N3000000160HS_mod').value='1';" size="75" tabindex="10" type="text" /><a href="JavaScript: openLookup('/_ui/common/data/LookupPage?lkfm=editPage&lknm=CF00N3000000160HS&lktp=' + document.getElementById('CF00N3000000160HS_lktp').value,670,document.getElementById('CF00N3000000160HS_mod').value,'&lksrch=' + escapeUTF(document.getElementById('CF00N3000000160HS').value),'maxw')" id="CF00N3000000160HS_lkwgt" onclick="setLastMousePosition(event)" tabindex="10" title="Academic Year Lookup (New Window)"><img src="/s.gif" alt="Academic Year Lookup (New Window)" class="lookupPopup" title="Academic Year Lookup (New Window)"></a></span></td></tr>
<tr><td class="labelCol requiredInput last"><label for="00N3000000160FR"><span class="requiredMark">*</span>Task</label><div class="textCounterOuter"><div class=""><div class="textCounter" id="00N3000000160FR_counter">32000 remaining</div></div></div></td><td class="data2Col last" colspan="3"><div class="requiredInput"><div class="requiredBlock"></div><textarea cols="75" id="00N3000000160FR" maxlength="32000" name="00N3000000160FR" onchange="handleTextAreaElementChange('00N3000000160FR', 32000, 'remaining', 'over limit');" onclick="handleTextAreaElementChange('00N3000000160FR', 32000, 'remaining', 'over limit');" onkeydown="handleTextAreaElementChange('00N3000000160FR', 32000, 'remaining', 'over limit');" onkeyup="handleTextAreaElementChange('00N3000000160FR', 32000, 'remaining', 'over limit');" onmousedown="handleTextAreaElementChange('00N3000000160FR', 32000, 'remaining', 'over limit');" rows="10" tabindex="11" type="text" wrap="soft"></textarea></div></td></tr>
</table></div><div class="pbSubheader tertiaryPalette" id="head_3_ep"><h3>Answer<span class="titleSeparatingColon">:</span></h3></div><div class="pbSubsection"><table class="detailList" border="0" cellpadding="0" cellspacing="0"><tr><td class="labelCol"><label for="00N3000000160H8"><font color=red>Note 1:</label></td><td class="data2Col" colspan="3"><span><select id="00N3000000160H8" name="00N3000000160H8" tabindex="12">
<option value="In the field below - Answers must be separated with either comma,semi-colon,colon" selected>In the field below - Answers must be separated with either comma,semi-colon,colon</option>
</select></span><script>new picklist('00N3000000160H8','00N3000000160H8',null,['In the field below - Answers must be separated with either comma,semi-colon,colon','In the field below - Answers must be separated with either comma,semi-colon,colon'],' id="00N3000000160H8" name="00N3000000160H8" tabindex="12"',true,true);</script>
</td></tr>
<tr><td class="labelCol last"><label for="00N3000000160Gy">Answers <font color=red>, : ; separated</label><div class="textCounterOuter"><div class="textCounterMiddle"><div class="textCounter" id="00N3000000160Gy_counter">32000 remaining</div></div></div></td><td class="data2Col last" colspan="3"><textarea cols="75" id="00N3000000160Gy" maxlength="32000" name="00N3000000160Gy" onchange="handleTextAreaElementChange('00N3000000160Gy', 32000, 'remaining', 'over limit');" onclick="handleTextAreaElementChange('00N3000000160Gy', 32000, 'remaining', 'over limit');" onkeydown="handleTextAreaElementChange('00N3000000160Gy', 32000, 'remaining', 'over limit');" onkeyup="handleTextAreaElementChange('00N3000000160Gy', 32000, 'remaining', 'over limit');" onmousedown="handleTextAreaElementChange('00N3000000160Gy', 32000, 'remaining', 'over limit');" rows="6" tabindex="13" type="text" wrap="soft"></textarea></td></tr>
</table></div></div><div class="pbBottomButtons"><table border="0" cellpadding="0" cellspacing="0"><tr><td class="pbTitle"><img src="/s.gif" alt="" width="1" height="1" class="minWidth" title="" /> </td><td class="pbButtonb"><input value=" Save " class="btn" name="save" tabindex="14" title="Save" type="submit" /> <input value="Save & New" class="btn" name="save_new" tabindex="15" title="Save & New" type="submit" /> <input value="Cancel" class="btn" name="cancel" tabindex="16" title="Cancel" type="submit" /></td></tr>
</table></div><div class="pbFooter secondaryPalette"><div class="bg"></div></div></div></form><script type="text/javascript">picklist.initAll()</script>
<!-- End page content -->
</td>
</tr>
</table>
</body></html>