Enable Save in IE9 mode
By Anatoly Mironov
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
function RTE\_GetEditorIFrame(strBaseElementID)
{ULSopi:;
var ifmEditor=null;
var doc=document;
if ((null !=doc.frames) && (doc.frames.length==0) && (doc.parentWindow.parent !=null))
{
doc=doc.parentWindow.parent.document;
}
if ((null !=doc.frames) && (doc.frames.length > 0))
{
var ifmContainer=doc.getElementById(RTE\_GetEditorIFrameID(strBaseElementID));
if (ifmContainer !=null)
{
ifmEditor=doc.frames(RTE\_GetEditorIFrameID(strBaseElementID));
}
}
return ifmEditor;
}
So it is document.frames("…"), not the usual document.frames["…"]. What is that VB-style about? Okay, the reason why this error isn’t raised in other browsers is just because this weird code isn’t run (Try to set break point there in Chrome or Firefox). And that’s why you never see Rich Text Editor toolbar in EditForm.aspx in Chrome and Firefox. To prove this, try to remove the Rich Text Column in your list. Then you can use “Save” button again, with IE9 mode! Now we know the reason. How can we solve it. To do so we must find out where javascript defines whether to run or not Rich Text Editor toolbar. First RTE_GetEditorIframe is invoked by RTE_ConvertTextAreaToRichEdit which is invoked by an inline script directly from NewForm.aspx:
if (browseris.ie5up
&& (browseris.win32 || browseris.win64bit)
&& !IsAccessibilityFeatureEnabled()){
RTE\_ConvertTextAreaToRichEdit("ctl00\_m\_g\_0a9abd43\_19a2\_461e\_b46f\_6a1ae22a7ff1\_ctl00\_ctl05\_ctl06\_ctl00\_ctl00\_ctl04\_ctl00\_ctl00\_TextField"
, true, false, "", "1044", null, true, null, null, null
,"Compatible", "\\u002ft001",null,null,null,null);
}
else{
document.write(" <br /><span class=\\"ms-formdescription\\"><a href='javascript:HelpWindowKey(\\"nsrichtext\\")'>Klikk her for hjelp med å legge til grunnleggende HTML-formatering.</a></span> <br />");
};
```So there it is where the fishy code is invoked. Okay how can we intervene here to enable Save button? All solutions are based on disabling the bad code which is used to "convert" textarea to RichEdit. 1. Solution number one override RTE\_ConvertTextAreaToRichEdit, just in style:
function RTE_ConvertTextAreaToRichEdit() {};
2\. Solution number two: override IsAccessibilityFeatureEnabled, or this one:
function SetIsAccessibilityFeatureEnabled(f) {ULSA13:; if (f) document.cookie=“WSS_AccessibilityFeature=true;path=/;”; else document.cookie=“WSS_AccessibilityFeature=false;path=/;”; var hiddenAnchor=document.getElementById(“HiddenAnchor”); var event; if (browseris.ie) event={ “srcElement” : hiddenAnchor , “fakeEvent” : 1, “enableStatus” : f}; else event={ “target” : hiddenAnchor , “fakeEvent” : 1, “enableStatus” : f}; if (hiddenAnchor==null || hiddenAnchor.onclick==null) return; hiddenAnchor.onclick(event); }
function Browseris () {ULSA13:; var agt=navigator.userAgent.toLowerCase(); this.osver=1.0; if (agt) { var stOSVer=agt.substring(agt.indexOf(“windows “)+11); this.osver=parseFloat(stOSVer); } this.major=parseInt(navigator.appVersion); this.nav=((agt.indexOf(‘mozilla’)!=-1)&&((agt.indexOf(‘spoofer’)==-1) && (agt.indexOf(‘compatible’)==-1))); this.nav6=this.nav && (this.major==5); this.nav6up=this.nav && (this.major >=5); this.nav7up=false; if (this.nav6up) { var navIdx=agt.indexOf(“netscape/”); if (navIdx >=0 ) this.nav7up=parseInt(agt.substring(navIdx+9)) >=7; } this.ie=(agt.indexOf(“msie”)!=-1); this.aol=this.ie && agt.indexOf(” aol “)!=-1; if (this.ie) { var stIEVer=agt.substring(agt.indexOf(“msie “)+5); this.iever=parseInt(stIEVer); this.verIEFull=parseFloat(stIEVer); } else this.iever=0; this.ie4up=this.ie && (this.major >=4); this.ie5up=this.ie && (this.iever >=5); this.ie55up=this.ie && (this.verIEFull >=5.5); this.ie6up=this.ie && (this.iever >=6); this.ie7down=this.ie && (this.iever =7); this.ie8standard=this.ie && document.documentMode && (document.documentMode==8); this.winnt=((agt.indexOf(“winnt”)!=-1)||(agt.indexOf(“windows nt”)!=-1)); this.win32=((this.major >=4) && (navigator.platform==“Win32”)) || (agt.indexOf(“win32”)!=-1) || (agt.indexOf(“32bit”)!=-1); this.win64bit=(agt.indexOf(“win64”)!=-1); this.win=this.winnt || this.win32 || this.win64bit; this.mac=(agt.indexOf(“mac”)!=-1); this.w3c=this.nav6up; this.safari=(agt.indexOf(“webkit”)!=-1); this.safari125up=false; this.safari3up=false; if (this.safari && this.major >=5) { var navIdx=agt.indexOf(“webkit/”); if (navIdx >=0) this.safari125up=parseInt(agt.substring(navIdx+7)) >=125; var verIdx=agt.indexOf(“version/”); if (verIdx >=0) this.safari3up=parseInt(agt.substring(verIdx+8)) >=3; } this.firefox=this.nav && (agt.indexOf(“firefox”) !=-1); this.firefox3up=false; this.firefox36up=false; if (this.firefox && this.major >=5) { var ffVerIdx=agt.indexOf(“firefox/”); if (ffVerIdx >=0) { var firefoxVStr=agt.substring(ffVerIdx+8); this.firefox3up=parseInt(firefoxVStr) >=3; this.firefox36up=parseFloat(firefoxVStr) >=3.6; } } } var browseris=new Browseris(); var bis=browseris;
var browseris = {};
ExecuteOrDelayUntilScriptLoaded(function() { var browseris = {}; }, “init.js”);
DISCLAIMER: It is just an exploration lab. There is no warranty that it will work across the whole site. Don't ever do such things things at home!
##### css3 fixers
If you just want to use css3 in your design and still use team functionality, take a look on [pie.htc](http://css3pie.com/), [jQuery.corner](http://jquery.malsup.com/corner/) or iecss3. **Update 2015-09-16 Other Related Issues** Recently me and my colleague had to fix this issue again in SharePoint 2010. What we found was failing select elements (Choice field or Lookup field) in forms. There are some js functions that do not run in other web browsers rather than in IE in IE9 mode. All fail because of the inability of getting custom html element attributes. \[code language="js" name="customscriptaftercore.js"\] //This is an override of FilterChoice (in core.js) //We override this line: var strOpts=ctrl.choices; -> var strOpts=ctrl.getAttribute("choices"); //The reason is that this does not work in IE9 mode //Don't forget this workaround. It might lead to other problems function FilterChoice\_new(opt, ctrl, strVal, filterVal) { var i; var cOpt=0; var bSelected=false; var strHtml=""; var strId=opt.id; var strName=opt.name; var strMatch=""; var strMatchVal=""; var strOpts=ctrl.getAttribute("choices"); //THIS ONE var rgopt=strOpts.split("|"); var x=AbsLeft(ctrl); var y=AbsTop(ctrl)+ctrl.offsetHeight; var elmWorkspace=document.getElementById("s4-workspace"); if(elmWorkspace) y -=AbsTop(elmWorkspace); var strHidden=ctrl.optHid; var iMac=rgopt.length - 1; var iMatch=-1; var unlimitedLength=false; var strSelectedLower=""; if (opt !=null && opt.selectedIndex >=0) { bSelected=true; strSelectedLower=opt.options\[opt.selectedIndex\].innerText; } for (i=0; i < rgopt.length; i=i+2) { var strOpt=rgopt\[i\]; while (i < iMac - 1 && rgopt\[i+1\].length==0) { strOpt=strOpt+"|"; i++; if (i < iMac - 1) { strOpt=strOpt+rgopt\[i+1\]; } i++; } var strValue=rgopt\[i+1\]; var strLowerOpt=strOpt.toLocaleLowerCase(); var strLowerVal=strVal.toLocaleLowerCase(); if (filterVal.length !=0) bSelected=true; if (strLowerOpt.indexOf(strLowerVal)==0) { var strLowerFilterVal=filterVal.toLocaleLowerCase(); if ((strLowerFilterVal.length !=0) && (strLowerOpt.indexOf(strLowerFilterVal)==0) && (strMatch.length==0)) bSelected=false; if (strLowerOpt.length > 20) { unlimitedLength=true; } if (!bSelected || strLowerOpt==strSelectedLower) { strHtml+="<option selected value=\\""+strValue+"\\">"+STSHtmlEncode(strOpt)+"</option>"; bSelected=true; strMatch=strOpt; strMatchVal=strValue; iMatch=i; } else { strHtml+="<option value=\\""+strValue+"\\">"+STSHtmlEncode(strOpt)+"</option>"; } cOpt++; } } var strHandler=" ondblclick=\\"HandleOptDblClick()\\" onkeydown=\\"HandleOptKeyDown()\\""; var strOptHtml=""; if (unlimitedLength) { strOptHtml="<select tabIndex=\\"-1\\" ctrl=\\""+ctrl.id+"\\" name=\\""+strName+"\\" id=\\""+strId+"\\""+strHandler; } else { strOptHtml="<select class=\\"ms-lookuptypeindropdown\\" tabIndex=\\"-1\\" ctrl=\\""+ctrl.id+"\\" name=\\""+strName+"\\" id=\\""+strId+"\\""+strHandler; } if (cOpt==0) { strOptHtml+=" style=\\"display:none;position:absolute;z-index:2;left:" + x + "px;top:" + y + "px\\" onfocusout=\\"OptLoseFocus(this)\\"></select>"; } else { strOptHtml+=" style=\\"position:absolute;z-index:2;left:"+x+"px;top:"+y+" size=\\"" +(cOpt <=8 ? cOpt : 8)+"\\""+ (cOpt==1 ? "multiple=\\"true\\"" : "") + " onfocusout=\\"OptLoseFocus(this)\\">"+ strHtml + "</select>"; } opt.outerHTML=strOptHtml; var hid=document.getElementById(strHidden); if (iMatch !=0 || rgopt\[1\] !="0" ) hid.value=strMatchVal; else hid.value="0"; if (iMatch !=0 || rgopt\[1\] !="0" ) return strMatch; else return ""; } function SetCtrlMatch\_new(ctrl, opt) { //ctrl.getAttribute("optHid") instead of ctrl.optHid var hid=document.getElementById(ctrl.getAttribute("optHid")); hid.value=opt.options\[opt.selectedIndex\].value; if (hid.value !=0) ctrl.match=opt.options\[opt.selectedIndex\].innerText; else ctrl.match=""; } function HandleOptDblClick\_new() { var opt=event.srcElement; //opt.getAttribute("ctrl") instead of opt.ctrl var ctrl=document.getElementById(opt.getAttribute("ctrl")); \_SetCtrlFromOpt(ctrl, opt); SetCtrlMatch(ctrl, opt); opt.style.display="none"; } function \_SetCtrlFromOpt\_new(ctrl, opt) { var hidId = ctrl.getAttribute("optHid"); if (!hidId) { return; } //ctrl.getAttribute("optHid") instead of ctrl.optHid var hid=document.getElementById(ctrl.getAttribute("optHid")); hid.value=opt.options\[opt.selectedIndex\].value; if (opt.options\[opt.selectedIndex\].value==0) { ctrl.value=opt.options\[opt.selectedIndex\].innerText; ctrl.match=""; } else { ctrl.value=opt.options\[opt.selectedIndex\].innerText; ctrl.match=ctrl.value; } } function HandleOptKeyDown\_new() { var opt=event.srcElement; //opt.getAttribute("ctrl") instead of opt.ctrl var ctrl=document.getElementById(opt.getAttribute("ctrl")); var key=event.keyCode; switch (key) { case 13: case 9: \_SetCtrlFromOpt(ctrl, opt) event.returnValue=false; opt.style.display="none"; return; default: break; } return; } ExecuteOrDelayUntilScriptLoaded(function() { FilterChoice = FilterChoice\_new; SetCtrlMatch = SetCtrlMatch\_new; HandleOptDblClick = HandleOptDblClick\_new; \_SetCtrlFromOpt = \_SetCtrlFromOpt\_new; HandleOptKeyDown = HandleOptKeyDown\_new; }, "core.js"); \[/code\]
## Comments from Wordpress.com
####
[Matthew](http://www.midlandcorp.com "nulloveride@gmail.com") - <time datetime="2012-03-13 22:39:02">Mar 2, 2012</time>
Actually, you can set it up so that you can use the Rich Text in IE9! You just have to override 4 functions in form.js (I created a file called form.ie9fix.js) and make sure it loads AFTER the "normal" form.js (or form.debug.js, whichever). The functions in question: RTE\_DD\_GetMenuFrame() RTE\_GetEditorInstanceVariables() RTE\_GetEditorIFrame() Each of these needs to be rewritten because it makes a call to document.frames() which is not proper notation in pretty much any browser, let alone IE9 (works in IE8-, though!). if you're searching you can find doc.frames( and replace the () with \[\] and you will be fine, because this is an array reference not a function. You can probably use this to fix the rich text issues in firefox, chrome, etc, as well. SharePoint has a lot of cases like this and some of them are pretty hard to nail down. This one I had to work even harder because the normal ScriptLink trick did not work. After the main ScriptLink tag on the master page, I added the following for each script where is the name of the script in question. ExecuteOrDelayUntilScriptLoaded(function(){ document.write('<script type="text/javascript" src="/\_layouts/1033/.ie9fix.js">'); }, '.js'); /\* rinse, repeat, for each script to be overridden \*/ Good luck! - Matt
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-15 08:44:45">Mar 4, 2012</time>
Thank you Matt! It was a great idea to just override and load them after form.js has been loaded. By the way, could you share your ie9fix.js code?
<hr />
####
[@SharePointOscar](http://sharepointoscar.com "me@sharepointoscar.com") - <time datetime="2012-07-11 06:10:17">Jul 3, 2012</time>
Great tips Matt and Anatoly! I had this issue on an Office365 project and used this as a fix :) -Oscar
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-07-11 11:12:17">Jul 3, 2012</time>
Glad you found this useful! Is the overriding of three functions fom form.js the only thing you did to get it worked?
<hr />
####
[@SharePointOscar](http://sharepointoscar.com "me@sharepointoscar.com") - <time datetime="2012-07-13 06:13:20">Jul 5, 2012</time>
Hey Anatoly, So the way I got it to work, is I created that JS file and included it on my master page. The file contains exactly this: function RTE\_DD\_GetMenuFrame() { var ifmMenu=null; var elemMenu=RTE\_DD\_GetMenuElement(); if (null !=elemMenu) { if (document.frames.length > 0) { ifmMenu=document.frames\[g\_strRTETextEditorPullDownMenuID\]; } else { if ((document.parentWindow !=null) && (document.parentWindow.frames !=null)) { ifmMenu=document.parentWindow.parent.document.frames\[g\_strRTETextEditorPullDownMenuID\]; } } } if (null==ifmMenu) { if (g\_fRTEFirstCallToGetMenu) { g\_fRTEFirstCallToGetMenu=false; return null; } } return ifmMenu; } function RTE\_GetEditorIFrame(strBaseElementID) { var ifmEditor=null; var doc=document; if ((null !=doc.frames) && (doc.frames.length==0) && (doc.parentWindow.parent !=null)) { doc=doc.parentWindow.parent.document; } if ((null !=doc.frames) && (doc.frames.length > 0)) { var ifmContainer=doc.getElementById(RTE\_GetEditorIFrameID(strBaseElementID)); if (ifmContainer !=null) { ifmEditor=doc.frames\[RTE\_GetEditorIFrameID(strBaseElementID)\]; } } return ifmEditor; } Then on my master page I simply added this before the tag: //fix an IE9 odd behaviour where Rich Textbox is not editable and cannot save. ExecuteOrDelayUntilScriptLoaded(function () { document.write(''); }, 'form.js'); Thanks so much for the tip and I hope this helps others as well! Cheers, Oscar
<hr />
####
[@SharePointOscar](http://sharepointoscar.com "me@sharepointoscar.com") - <time datetime="2012-07-13 06:14:26">Jul 5, 2012</time>
Love the name of the company you work for too :) -Oscar
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-08-14 09:43:05">Aug 2, 2012</time>
Thank you! Bool is actually a very nice company, not just the name!
<hr />
####
[Stackzzz]( "speeds_03@msn.com") - <time datetime="2015-01-31 22:35:23">Jan 6, 2015</time>
Hey Matt, really need some help with this, shoot me an email at speeds\_03@msn.com
<hr />
####
[Pandy Legend](http://pandylegend.wordpress.com "strangefrontier@hotmail.com") - <time datetime="2014-11-24 16:00:15">Nov 1, 2014</time>
I implemented said fix and it works great, but it seems only for me! All other users still cannot save. Why would this be so? Are there any special permission settings for custom JS files? The pages are definitely not cached versions as I see the new code in the head, but they seem to have no effect except for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-11-24 17:30:31">Nov 1, 2014</time>
Could it be as simple as your user do not get the right js-file. Check if their overriden functions are "right". I have faced this problem sometimes, I have updated a js file in Style Library but forgot to publish it. I am not saying you have this problem, but I'd suggest this as a first step in the investigation.
<hr />
####
[Pandy Legend](http://pandylegend.wordpress.com "strangefrontier@hotmail.com") - <time datetime="2014-11-25 09:23:26">Nov 2, 2014</time>
Hi Anatoly, thanks for the reply. I saved the new file in the same folder on the server as the form.js file (/\_layouts/1033/FORM-IE9FIX.JS), not in a Style Library within SP itself. How would I apply permissions to it/publish it?
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-11-25 09:54:38">Nov 2, 2014</time>
Well, then you cannot publish it. It should be available for all directly. Nevertheless you should verify that other users get the updated js.... Use a Developer Console in your browser to check that.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-11-25 12:47:54">Nov 2, 2014</time>
Good! Thanks for sharing your findings!
<hr />
####
[Pandy Legend](http://pandylegend.wordpress.com "strangefrontier@hotmail.com") - <time datetime="2014-11-25 12:34:37">Nov 2, 2014</time>
It turns out that the fix wasn't running even for me. I recently "upgraded" to IE11 whereas all my colleagues are on IE10. IE11 doesn't have the issues with the save button or the rich text editor it seems. It does still have other problems, with the People Picker for example. That led me to http://sharepoint.stackexchange.com/questions/27251/hotfix-for-problem-with-sharepoint-peopleeditor-in-ie-9 where it suggests that "using the usual tricks to get it to load after the original entityeditor.js from SharePoint did not work". I followed the suggestion to add the js at the end of the master page and now it all works in IE9, 10 and 11. (At least, the problems mentioned here and on the StackExchange page!).
<hr />