How to restrict my website to IE8 and higher versions only - html

My website should only work for IE8 and higher versions .
How can I restrict the use of version change using developer tools to the users?
Is there a way to restrict that using Jquery?
This is my javascript to find out the browser mode and document mode of the user agent,but I don't restrict the user change the browser and document modes to IE7.
<script type="text/javascript">
/*
* Author: Rob Reid
* CreateDate: 20-Mar-09
* Description: Little helper function to return details about IE 8 and its various compatibility settings either use as it is
* or incorporate into a browser object. Remember browser sniffing is not the best way to detect user-settings as spoofing is
* very common so use with caution.
*/
$(function(){
var browserInfo = IEVersion();
console.log($('meta'));
alert(browserInfo.DocMode);
$('meta').attr('rel','IE=7');
});
function IEVersion()
{
var _n = navigator, _w = window, _d = document;
var version = "NA";
var na = _n.userAgent;
var ieDocMode = "NA";
var ie8BrowserMode = "NA";
// Look for msie and make sure its not opera in disguise
if (/msie/i.test(na) && (!_w.opera))
{
// also check for spoofers by checking known IE objects
if (_w.attachEvent && _w.ActiveXObject)
{
// Get version displayed in UA although if its IE 8 running in 7 or compat mode it will appear as 7
version = (na.match(/.+ie\s([\d.]+)/i) || [])[1];
// Its IE 8 pretending to be IE 7 or in compat mode
if (parseInt(version) == 7)
{
// documentMode is only supported in IE 8 so we know if its here its really IE 8
if (_d.documentMode)
{
version = 8; //reset? change if you need to
// IE in Compat mode will mention Trident in the useragent
if (/trident\/\d/i.test(na))
{
ie8BrowserMode = "Compat Mode";
// if it doesn't then its running in IE 7 mode
} else
{
ie8BrowserMode = "IE 7 Mode";
}
}
} else if (parseInt(version) == 8)
{
// IE 8 will always have documentMode available
if (_d.documentMode) { ie8BrowserMode = "IE 8 Mode"; }
}
// If we are in IE 8 (any mode) or previous versions of IE we check for the documentMode or compatMode for pre 8 versions
ieDocMode = (_d.documentMode) ? _d.documentMode : (_d.compatMode && _d.compatMode == "CSS1Compat") ? 7 : 5; //default to quirks mode IE5
}
}
return {
"UserAgent": na,
"Version": version,
"BrowserMode": ie8BrowserMode,
"DocMode": ieDocMode
}
}
function DisplayInfo()
{
var browserInfo = IEVersion();
alert('UserAgent: ' + browserInfo.UserAgent + '\nVersion: ' + browserInfo.Version + '\nBrowserMode: ' + browserInfo.BrowserMode + '\nDocMode: ' + browserInfo.DocMode);
}

Try not to as this will annoy many possible users and force them to a competitors website.
Admittedly you might not be able to do much about the browser of choice if you are using an ActiveX control for instance.

You can use some Conditional comments like thus:
<!--[if IE 6]>
Special instructions for IE 6 here
<![endif]-->
You can find more about this here

how to restrict that using jquery
Just not possible. Doesn't matter if it is good practice or bad. You just can't change browser settings thru jQuery or Javascript for that matter.
When ever the user is trying to change the version using developer tools
I think what you can do is use this meta tag as the first one inside head :
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
This will force the IE out of compatibility mode and use the latest version, whatever it is.
When you use a server-side framework like ASP.Net, you cannot be sure that this will remain as the first tag inside head. So, for example in ASP.Net you can write this in the PreInit:
HttpContext.Current.Response.AddHeader("X-UA-Compatible", "IE=Edge")
Alternatively, you can also push the header from the web server e.g. IIS.

Related

Is there a way to have a bookmark be created upon clicking a button/link?

I'm trying to figure out if it's possible to make it so that if you click a link or button, a bookmark will be created. Anything that comes up on Google has to do with ebooks, and I can't seem to find anything. If anyone has the answer, it would be a huge help!
function addFavorites(a) {
pageTitle = document.title;
pageURL = document.location;
try {
// Internet Explorer solution
eval("window.external.AddFa-vorite(pageURL, pageTitle)".replace(/-/g, ''));
} catch (e) {
try {
// Mozilla Firefox solution
window.sidebar.addPanel(pageTitle, pageURL, "");
} catch (e) {
// Opera solution
if (typeof(opera) == "object") {
a.rel = "sidebar";
a.title = pageTitle;
a.url = pageURL;
return true;
} else {
// The rest browsers (i.e Chrome, Safari)
alert('Press ' + (navigator.userAgent.toLowerCase().indexOf('mac') != -1 ? 'Cmd' : 'Ctrl') + '+D to bookmark this page.');
}
}
}
return false;
}
Add to Favorites
Source: https://rudrastyh.com/javascript/favorite-button.html
Be aware of eval()
eval() may be a dangerous function under certain circumstances, which executes the code it's passed with the privileges of the caller.
Get advised by Mozilla.org and use with caution
No, there's no stright forward way for that.
Opera, Google Chrome and Safari do not provide a way to add new elements to the Favorites (Bookmarks) from JavaScript.
There was an API for that however, which is the Window.external API, and I believe it used to work as window.external.AddFavorite() in Internet Explorer, and window.sidebar.addPanel() in Firefox (obsolete, deprecated, i.e. dead, see for the API).
Not sure this info would help, but you might have to create a browser extension for that, then connect your button with your extension, this way you can ensure its stability.
My suggestion is to simply ask the users to bookmark the webpage they're in if that would help to solve the problem you're trying to solve (not sure what you're trying to create).

HTML5 input type placeholder is not working in IE

I am using HTML5 for one of my project. There I am using input placeholder property to show some default text. It's not working in IE. Any solution for this?
If you are using javascript in your project, you can add this peace of code and it will provide a placeholder through javascript to your inputs.
function supports_input_placeholder() {
var i = document.createElement('input');
return 'placeholder' in i;
}
if (!supports_input_placeholder()) {
var fields = document.getElementsByTagName('INPUT');
for (var i = 0; i < fields.length; i++) {
if (fields[i].hasAttribute('placeholder')) {
fields[i].defaultValue = fields[i].getAttribute('placeholder');
fields[i].onfocus = function () { if (this.value == this.defaultValue) this.value = ''; }
fields[i].onblur = function () { if (this.value == '') this.value = this.defaultValue; }
}
}
}
Placeholder is not supported until IE 10.
http://caniuse.com/#feat=input-placeholder
You can use a polyfill to support it in IE.
See the top answer on this thread as it has a very good explanation:
Input placeholders for Internet Explorer
Older version of IE don't support html placeholders. Therefore, you will need to use a javascript solution like Placeholder.js. It automatically detects the placeholder attributes in your input elements and utilizes a cross-browser solution to show them.
Use jQuery placeholder. HTML5 placeholder is not supported by standard HTML5 declaration until Internet Explorer 10.
try Placeholders.js
it is light weight and also works well in IE 6
Alternative option would be to show the "name:" text on IE < 10
<!--[if lt IE 10]><style>.show-ie{display:block;}</style><![endif]-->

IE 9 Compatibility for Javascripts: ChildNode, SetAttribute

Many of the Javascripts functions are not working in IE 9.
To be specific, we have constructed some HTML contents dynamically. Now, when we tried to acess the content of an HTML table by using childNode element, the object is not completely retrieved into it.
But, when we run the same in IE 9-compatibility mode we were able to get it.
Code sample:
var _object = document.getElementById(strTableId).childNodes[0]
for (var iCount = 0; iCount < _object.childNodes.length; iCount++) {
if (_object.childNodes[iCount]) {
_object.childNodes[iCount].style.backgroundColor = 'white';
_object.childNodes[iCount].style.color = 'black'
}
}
Now, when we debug the code, we could see the objects existing in the variables, but the style properties and others are not accessible. Hence, the backgroundcolor line throws a javascript exeption.
Kindly help!
IE 9 not support ChildNodes[0]. We can use children[0] instead of ChildNodes[0]
Mohan.K

Correct way to use Modernizr to detect IE?

I wanted to use the Modernizr JS library to detect for some browser properties to determine what content to show or not show.
I have an app called Pano2VR which outputs both HTML5 and SWF. I need the HTML5 for iOS device users.
However, IE does not render this "HTML5" output at all. It seems their output uses CSS3 3D transforms and WebGL, one or more apparently unsupported in IE9.
So, for those users I need to display the Flash version. I was planning to use an IFRAME and either pass the SRC via a Modernizr script or document.write out the correct IFRAME code depending on browser.
All of which leads to how do I use Modernizr to detect simply IE or not IE? Or detect for CSS 3d transforms?
Or is there another way to do this?
Modernizr doesn't detect browsers as such, it detects which feature and capability are present and this is the whole jist of what it's trying to do.
You could try hooking in a simple detection script like this and then using it to make your choice. I've included Version Detection as well just in case that's needed. If you only want to check of any version of IE you could just look for the navigator.userAgent having a value of "MSIE".
var BrowserDetect = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "Other";
this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "Unknown";
},
searchString: function (data) {
for (var i = 0; i < data.length; i++) {
var dataString = data[i].string;
this.versionSearchString = data[i].subString;
if (dataString.indexOf(data[i].subString) !== -1) {
return data[i].identity;
}
}
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index === -1) {
return;
}
var rv = dataString.indexOf("rv:");
if (this.versionSearchString === "Trident" && rv !== -1) {
return parseFloat(dataString.substring(rv + 3));
} else {
return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
}
},
dataBrowser: [
{string: navigator.userAgent, subString: "Edge", identity: "MS Edge"},
{string: navigator.userAgent, subString: "MSIE", identity: "Explorer"},
{string: navigator.userAgent, subString: "Trident", identity: "Explorer"},
{string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
{string: navigator.userAgent, subString: "Opera", identity: "Opera"},
{string: navigator.userAgent, subString: "OPR", identity: "Opera"},
{string: navigator.userAgent, subString: "Chrome", identity: "Chrome"},
{string: navigator.userAgent, subString: "Safari", identity: "Safari"}
]
};
BrowserDetect.init();
document.write("You are using <b>" + BrowserDetect.browser + "</b> with version <b>" + BrowserDetect.version + "</b>");
You can then simply check for:
BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;
You can use Modernizr to detect simply IE or not IE, by checking for SVG SMIL animation support.
If you've included SMIL feature detection in your Modernizr setup, you can use a simple CSS approach, and target the .no-smil class that Modernizr applies to the html element:
html.no-smil {
/* IE/Edge specific styles go here - hide HTML5 content and show Flash content */
}
Alternatively, you could use Modernizr with a simple JavaScript approach, like so:
if ( Modernizr.smil ) {
/* set HTML5 content */
} else {
/* set IE/Edge/Flash content */
}
Bear in mind, IE/Edge might someday support SMIL, but there are currently no plans to do so.
For reference, here's a link to the SMIL compatibility chart at caniuse.com.
Detecting CSS 3D transforms
Modernizr can detect CSS 3D transforms, yeah. The truthiness of Modernizr.csstransforms3d will tell you if the browser supports them.
The above link lets you select which tests to include in a Modernizr build, and the option you're looking for is available there.
Detecting IE specifically
Alternatively, as user356990 answered, you can use conditional comments if you're searching for IE and IE alone. Rather than creating a global variable, you can use HTML5 Boilerplate's <html> conditional comments trick to assign a class:
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
If you already have jQuery initialised, you can just check with $('html').hasClass('lt-ie9'). If you need to check which IE version you're in so you can conditionally load either jQuery 1.x or 2.x, you can do something like this:
myChecks.ltIE9 = (function(){
var htmlElemClasses = document.querySelector('html').className.split(' ');
if (!htmlElemClasses){return false;}
for (var i = 0; i < htmlElemClasses.length; i += 1 ){
var klass = htmlElemClasses[i];
if (klass === 'lt-ie9'){
return true;
}
}
return false;
}());
N.B. IE conditional comments are only supported up to IE9 inclusive. From IE10 onwards, Microsoft encourages using feature detection rather than browser detection.
Whichever method you choose, you'd then test with
if ( myChecks.ltIE9 || Modernizr.csstransforms3d ){
// iframe or flash fallback
}
Don't take that || literally, of course.
If you're looking for a JS version (using a combination of feature detection and UA sniffing) of what html5 boilerplate used to do:
var IE = (!! window.ActiveXObject && +(/msie\s(\d+)/i.exec(navigator.userAgent)[1])) || NaN;
if (IE < 9) {
document.documentElement.className += ' lt-ie9' + ' ie' + IE;
}
Well, after doing more research on this topic I ended up using following solution for targeting IE 10+.
As IE10&11 are the only browsers which support the -ms-high-contrast media query, that is a good option without any JS:
#media screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none) {
/* IE10+ specific styles go here */
}
Works perfectly.
CSS tricks have a good solution to target IE 11:
http://css-tricks.com/ie-10-specific-styles/
The .NET and Trident/7.0 are unique to IE so can be used to detect IE version 11.
The code then adds the User Agent string to the html tag with the attribute 'data-useragent', so IE 11 can be targeted specifically...
I agree we should test for capabilities, but it's hard to find a simple answer to "what capabilities are supported by 'modern browsers' but not 'old browsers'?"
So I fired up a bunch of browsers and inspected Modernizer directly.
I added a few capabilities I definitely require, and then I added "inputtypes.color" because that seems to cover all the major browsers I care about: Chrome, Firefox, Opera, Edge...and NOT IE11. Now I can gently suggest the user would be better off with Chrome/Opera/Firefox/Edge.
This is what I use - you can edit the list of things to test for your particular case.
Returns false if any of the capabilities are missing.
/**
* Check browser capabilities.
*/
public CheckBrowser(): boolean
{
let tests = ["csstransforms3d", "canvas", "flexbox", "webgl", "inputtypes.color"];
// Lets see what each browser can do and compare...
//console.log("Modernizr", Modernizr);
for (let i = 0; i < tests.length; i++)
{
// if you don't test for nested properties then you can just use
// "if (!Modernizr[tests[i]])" instead
if (!ObjectUtils.GetProperty(Modernizr, tests[i]))
{
console.error("Browser Capability missing: " + tests[i]);
return false;
}
}
return true;
}
And here is that GetProperty method which is needed for "inputtypes.color".
/**
* Get a property value from the target object specified by name.
*
* The property name may be a nested property, e.g. "Contact.Address.Code".
*
* Returns undefined if a property is undefined (an existing property could be null).
* If the property exists and has the value undefined then good luck with that.
*/
public static GetProperty(target: any, propertyName: string): any
{
if (!(target && propertyName))
{
return undefined;
}
var o = target;
propertyName = propertyName.replace(/\[(\w+)\]/g, ".$1");
propertyName = propertyName.replace(/^\./, "");
var a = propertyName.split(".");
while (a.length)
{
var n = a.shift();
if (n in o)
{
o = o[n];
if (o == null)
{
return undefined;
}
}
else
{
return undefined;
}
}
return o;
}
I needed to detect IE vs most everything else and I didn't want to depend on the UA string. I found that using es6number with Modernizr did exactly what I wanted. I don't have much concern with this changing as I don't expect IE to ever support ES6 Number. So now I know the difference between any version of IE vs Edge/Chrome/Firefox/Opera/Safari.
More details here: http://caniuse.com/#feat=es6-number
Note that I'm not really concerned about Opera Mini false negatives. You might be.
You can use the < !-- [if IE] >
hack to set a global js variable that then gets tested in your normal js code. A bit ugly but has worked well for me.

SSRS Report Viewer Control Browser Compatibility

How compatible is the MS Report Viewer Control with browsers like Firefox and Safari?
Please also post if you know any 3rd party report viewers for SSRS.
Edit - 2016/2017 Update
SSRS 2016+ can be said to be cross-browser compatible.
Table borders aren't displaying right in IE10, but IE10 is dying out anyway.
In the rest of the browsers, it's fine.
You still need to register add_pageLoaded to translate the parameter prompts.
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () { fixReportingServices('rpt-container'); });
Also, like in versions < 2016, you need to add PageCountMode="Actual" to RS:ReportViewerHost control.
<RS:ReportViewerHost ID="ReportViewerControl" PageCountMode="Actual" runat="server" />
if you want to have meaningful paging numbers.
Also, there's a problem when you set the language in the query string with datepickers (with SSRS < 2016 as well). You need to set context.Request.UserLanguages[i] to the language specified in the query-string in context.BeginRequest in a HTTP-Module, if you want datepicker to work with a non-browser language.
Also, you need to add the X-Frame-Options and Content-Security-Policy HTTP-headers in each HTTP-response, if you want to use SSRS in an iframe in the internet securely. See my github-repository for details.
</EndEdit>
Pre-2016:
I can tell you, I have 9 years experience with the damn thing (SSRS 2005, SSRS 2008 R1 & R2, 2012, and SSRS 2014).
Let me assure you that because SSRS HTML reports depend on IE5-Quirksmode, there is no chance in hell they will ever render correctly in any browser other than Internet Explorer (IE < 10 I might be inclined to add).
IF you have admin access to the reportserver, and I stress the IF, you can add jQuery routines and CSS on the ReportViewer page to correct the most basic problems (like that you don't see more than 1cm of the report), but otherwise, the HTML rendering will still look absolutely horrible (margins, table borders, picture paddings, column size, textfield-size, title and/or pagenumber-alignment, etc., in short - just about anything)
Of course, the ActiveX printer control can only ever work in InternetExplorer (on Windows), because only there ActiveX are supported.
Let me also assure you, there is absolutely no way in hell to get ReportManager working in any other browser than IE.
As for Internet Explorer support, it should be mentioned, that starting as of IE version 10, IE defaults to webkit-quirksmode (for compatibility reasons) instead of IE5 quirksmode, so the HTML rendered will look equally horrible as in Chrome/Firefox/Safari for IE 10+, unless you added meta xua-compatible IE5 in the ReportViewer.aspx page.
The latter might not apply for Intranet, as IE automatically falls back to IE 7 compatibility mode when it's on an intranet site (but only in any Windows version < 8).
In Windows 8, localhost links and computername links (can't add the http:// in stackoverflow posts) are not assigned to the local intranet zone (probably as quick hack so IE doesn't fall back to IE7 compatibility mode), and therefore, Windows authentication will FAIL.
It should also be mentioned that it's not possible to add meta xua-compatible IE5 for ReportManager, because there is no page you can edit (compiled non-updateable ASP.NET website-project... ).
And that short of using the dev-tools to switch reportmanager in quirksmode, it's not possible to use ReportManager in IE 10+.
Then, another thing to mention is, that starting as of IE9, IE inherits the doctype of iframe elements from the parent page, and there is no way in hell to change that either (without changing the parent page to the desired child-page doc-mode).
So if you were clever enough to use iframes for the reports, because there is no way in hell any sane person wants popups in the age of popup-blockers, the report page will inherit the parent page's doctype. If that isn't IE5-QuirksMode, it will render the reports equally horrible as on Safari/Chrome/Firefox/Opera for any IE > 8, irrespecive of any possible meta xua-compatible ie5 tag in ReportViewer.aspx.
As for alternatives, for free and with a similar feature-set, there is only Eclipse BIRT (fortunately, the HTML rendering isn't similar).
It should be mentioned that BIRT, although licensed under the Eclipse Public License, uses SUN Java and therefore you are using Oracle technology, which is subject to its respective licensing terms.
Also, you are using non-Microsoft technology, and the Excel-Sheets BIRT renders are actually XML files, which will produce (who would have guessed) a rather alarming warning when opening in Office 2010+.
Then, for a rather large fee, there is http://www.stimulsoft.com reports, and Telerik reports.
From the technical looks of it, I'd recommend stimulsoft reports, but: disclaimer, i haven't used either of these, because they aren't free.
As for alternative SSRS rendering engines (not viewers btw), there is only www.fyireporting.com/‎, which has a fork here http://www.codeproject.com/Articles/138271/An-Open-Source-RDL-Engine.
But fyiReporting is incomplete and work in progress (if not abandoned), so I would refrain from using it.
Bottom line, if your product is IE & windows only, with windows version < 8 (and no - not <= just in case you haven't been paying attention), in intranet, called from pop-ups and not iframes, then go with SSRS.
For anything else, use stimulsoft reports (the problem is, you have to redo all your reports, as there is no automated migration - not even a non-working one).
PS:
And by adding "a little javascript", i mean the below thing(2008 R1 Edition, won't work on 2008R2+, may work on 2005, and note that you need to embed jQuery and jQuery Migrate in an inline-script tag, if the client PC's don't have access to http(s)://ajax.aspnetcdn.com [note: putting the scripts into the Pages folder and adding a relative or absolute link won't work...]):
<%# Register TagPrefix="RS" Namespace="Microsoft.ReportingServices.WebServer" Assembly="ReportingServicesWebServer" %>
<%# Page Language="C#" AutoEventWireup="true" Inherits="Microsoft.ReportingServices.WebServer.ReportViewerPage" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<%= System.Web.HttpContext.Current.Request.Browser.Browser == "IE" && System.Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(System.Convert.ToString(System.Web.HttpContext.Current.Request.QueryString), "stylesheet", System.Globalization.CompareOptions.IgnoreCase) == -1 ? (System.Web.HttpContext.Current.Request.Browser.Browser != "IE" ? "": "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=5\">") : "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">" %>
<head id="headID" runat="server">
<title>Report Viewer</title>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jquery.migrate/jquery-migrate-1.1.0.min.js"></script>
<script type="text/javascript">
var bInFrameOrIframe = false;
var iLanguageIndex = 0;
var language = "DE_LOL";
var UpdateLock = false;
if (window.self === window.top) {
// alert("true");
// not in a frame
// Use IE5 quirksmode
//document.writeln('<meta http-equiv="X-UA-Compatible" content="IE=5" />');
bInFrameOrIframe = false
}
else {
// in a frame, FMS
bInFrameOrIframe = true;
}
function TranslateParameterPrompts() {
//mTo = false;
$("table[id^='ParametersGridReportViewerControl'] span").each(function(index) {
var strText = $(this).text();
if (strText != null && strText.indexOf('/') != -1) {
strText = strText.split('/');
if (iLanguageIndex < strText.length)
strText = strText[iLanguageIndex];
else {
if (strText.length > 0)
strText = strText[0];
}
$(this).text(strText);
}
});
//setTimeout(function(){mTo = true}, 5000);
}
function setTableSize() {
//$("[id$='ReportViewerControl']")
$(
$(
$("#ReportFrameReportViewerControl")[0].contentWindow.document
)
.find("[id$='report']")[0].contentWindow.document.body
).find('*')
.each(function() {
//console.log("Processing an element");
//var cls = $(this).attr("class");
try {
// Don't add a border to sort-arrow
if ($(this).is('img')) {
return;
}
var anywidth = $(this).css('width');
var anywidth = parseFloat(anywidth);
//console.log("anywidth: " + anywidth);
//var lol = $(this).css('borderLeftWidth');
var blw = $(this).css('border-left-width');
var brw = $(this).css('border-right-width');
var btw = $(this).css('border-top-width');
var bbw = $(this).css('border-bottom-width');
var borls = $(this).css('border-left-style') == "solid";
var borrs = $(this).css('border-right-style') == "solid";
var borts = $(this).css('border-top-style') == "solid";
var borbs = $(this).css('border-bottom-style') == "solid";
var blw = parseFloat(blw);
var brw = parseFloat(brw);
var btw = parseFloat(btw);
var bbw = parseFloat(bbw);
//parseInt($(this).css("borderRightWidth"))
//console.log(parseInt($(this).css("borderLeftWidth")));
UpdateLock = true;
// Set width to 1px where 0px
if (anywidth == 0)
$(this).css('width', '1px');
if (borls && blw == 0.0 || (blw > 0.0 && blw < 1.0)) {
//console.log("setting border width");
$(this).css('border-left-width', '1px');
}
if (borrs && brw == 0.0 || (brw > 0.0 && brw < 1.0)) {
$(this).css('border-right-width', '1px');
}
if (borts && btw == 0.0 || (btw > 0.0 && btw < 1.0)) {
$(this).css('border-top-width', '1px');
}
if (borbs && bbw == 0.0 || (bbw > 0.0 && bbw < 1.0)) {
$(this).css('border-bottom-width', '1px');
}
UpdateLock = false;
}
catch (ex) {
UpdateLock = false;
//console.log(ex);
}
}); // End $('*').each
// console.log("loop");
var $img = $("img[onload^='this.fitproportional=true']");
if ($img == null) {
// console.log("img is null");
return;
}
var $div = $img.parent();
if ($div == null) {
// console.log("div is null");
return;
}
UpdateLock = true;
{
$img.removeAttr("height");
$img.css('max-width', '100%')
$img.css('max-height', '100%')
$div.css('text-align', 'right');
var divMinWidth = parseFloat($div.css('min-width'));
var divWidth = parseFloat($div.css('width'));
var divMinHeight = parseFloat($div.css('min-height'));
var divHeight = parseFloat($div.css('height'));
// console.log("width: " + divWidth);
// console.log("height: " + divHeight);
// console.log("min-width: " + divMinWidth);
// console.log("min-height: " + divMinHeight);
if (divMinWidth != 0)
$div.css('width', $div.css('min-width'));
if (divMinHeight != 0)
$div.css('height', $div.css('min-height'));
}
UpdateLock = false;
}
$(document).ready(function() {
switch (language) {
case "fr":
iLanguageIndex = 1;
break;
case "it":
iLanguageIndex = 2;
break;
case "en":
iLanguageIndex = 3;
break;
default: // "DE"
iLanguageIndex = 0;
}
TranslateParameterPrompts();
// setInterval(function() { TranslateParameterPrompts() }, 100);
if ($.browser.msie && !bInFrameOrIframe)
return;
// if ($.browser.webkit)
//setTableSize();
$("[id$='ReportFrameReportViewerControl']").load(function() {
//setNewHeight();
//alert("Loading");
setTableSize();
$(
$("[id$='ReportFrameReportViewerControl']")[0].contentWindow.document
)
.find("[id$='report']").load(function() {
//alert("load report");
setTableSize();
}
); // End load #report
}); // End Function load #ReportFrameReportViewerControl
}); // End Function document.ready
</script>
</head>
<body style="margin: 0px; overflow: auto">
<form style="width:100%;height:100%" runat="server" ID="ReportViewerForm">
<RS:ReportViewerHost ID="ReportViewerControl" runat="server" />
</form>
</body>
</html>
Note: UpdateLock stems from 2012 backport and is not really used here, and language stems from backport too, setInterval on TranslateParameterPrompts is necessary in 2012
and function
for 2012 has only the little addition of "label" in the jQuery selector...
function TranslateParameterPrompts() {
//mTo = false;
$("table[id^='ParametersGridReportViewerControl'] label span").each(function(index) {
var strText = $(this).text();
if (strText != null && strText.indexOf('/') != -1) {
strText = strText.split('/');
if (iLanguageIndex < strText.length)
strText = strText[iLanguageIndex];
else
{
if(strText.length > 0)
strText = strText[0];
}
$(this).text(strText);
}
});
//setTimeout(function(){mTo = true}, 5000);
}
Infering the language from the browser language goes like this, btw:
<script type="text/javascript">
language = <%= System.Web.HttpContext.Current.Request.UserLanguages != null ? "\"" + System.Convert.ToString(System.Web.HttpContext.Current.Request.UserLanguages[0]) + "\"" : "null" %>;
if(language == null)
language = window.navigator.userLanguage || window.navigator.language;
if(language != null)
language = language.substr(0,2).toLowerCase();
</script>
And in 2012 you need to Dispose of the session cookies, otherwise you get "HTTP 400: Header too long" after opening about 120 reports:
<script type="text/C#" runat="server">
protected string ClearSessionKeepAliveCookiesToPreventHttp400HeaderTooLong()
{
if(Request == null || Request.Cookies == null)
return "";
if(Request.Cookies.Count < 60)
return "";
// System.Web.HttpContext.Current.Response.Write("<h1>"+Request.Cookies.Count.ToString()+"</h1>");
for(int i = 0; i < System.Web.HttpContext.Current.Request.Cookies.Count; ++i)
{
if(StringComparer.OrdinalIgnoreCase.Equals(Request.Cookies[i].Name, System.Web.Security.FormsAuthentication.FormsCookieName))
continue;
if(!Request.Cookies[i].Name.EndsWith("_SKA", System.StringComparison.OrdinalIgnoreCase))
continue;
if(i > 60)
break;
//System.Web.HttpContext.Current.Response.Write("<h1>"+Request.Cookies[i].Name+"</h1>");
System.Web.HttpCookie c = new System.Web.HttpCookie( Request.Cookies[i].Name );
//c.Expires = System.DateTime.Now.AddDays( -1 );
c.Expires = new System.DateTime(1970, 1 ,1);
c.Path = Request.ApplicationPath + "/Pages";
c.Secure = false;
c.HttpOnly = true;
// http://stackoverflow.com/questions/5517273/httpcookiecollection-add-vs-httpcookiecollection-set-does-the-request-cookies
//Response.Cookies[Request.Cookies[i].Name] = c;
//Response.Cookies.Add(c);
Response.Cookies.Set(c);
}
return "";
}
</script>
And on 2012, you need to listen to content update, because it uses Microsoft Ajax controls
function cbOnContentUpdate() {
//console.log("content update");
alterTableBorderWidth();
// TranslateParameterPrompts();
} // End Callback cbOnContentUpdate
var hLastTimeout = null;
function queueUpdate() {
if (UpdateLock)
return;
if (hLastTimeout != null)
clearTimeout(hLastTimeout);
hLastTimeout = window.setTimeout(function() { cbOnContentUpdate(); }, 50);
//window.setTimeout(function() { cbOnContentUpdate(); }, 3000);
} // End Function queueUpdate
$(document).ready(function() {
switch (language) {
case "fr":
iLanguageIndex = 1;
break;
case "it":
iLanguageIndex = 2;
break;
case "en":
iLanguageIndex = 3;
break;
default: // "DE"
iLanguageIndex = 0;
}
setInterval(function() { TranslateParameterPrompts() }, 100);
// opt-out for non-framed IE, because that crook supports IE5-Quirks (framed takes parent-doctype in IE >= 9)
if ($.browser.msie && !areWeInFrame())
return;
// if ($.browser.webkit)
// console.log('Setting event listener!');
// http://stackoverflow.com/questions/4979738/fire-jquery-event-on-div-change
//$("[id$='ReportViewerControl']").bind('DOMNodeInserted DOMNodeRemoved', function(event) {
//$("[id$='ReportArea']")
$("body")
.bind('DOMNodeInserted DOMNodeRemoved DOMSubtreeModified', function(event) {
if (event.type == 'DOMNodeInserted') {
//console.log('Content added! Current content:' + '\n\n' + this.innerHTML);
//console.log('Content added!');
queueUpdate();
}
else {
//console.log('Content removed! Current content:' + '\n\n' + this.innerHTML);
//console.log('Content removed!');
queueUpdate();
}
}); // End Bind IRM
}); // End Function $(document).ready
And note that for 2012, setTableSize is alterTableBorderWidth, and the selector goes like this:
function alterTableBorderWidth()
{
//$('*')
$("[id$='ReportViewerControl']").find('*')
.each(function() {
Btw, if you want to remove the PRINT icon, because it's only a source of sorrow, that goes like this (for German, English, French and Italian [the languages spoken in Switzerland + English]).
This CSS is for 2008 R1, don't know and care if it's the same in 2012.
input[type="image"][title="Drucken"], input[type="image"][title="Print"], input[type="image"][title="Imprimer"], input[type="image"][title="Stampa"]
{
display: none !important;
}
And if that still doesn't deter you, then go right ahead and use forms authentication in SSRS 2012 (hint 1: there is no ms-provied sample as for 2005-2008R2, you need to write it yourself) ;)
Hint2: if you followed hint1, forms authentication redirect doesn't work when you have a colon in the URL [bug?], you can steal the code from mono and write your own redirect.
Hint3: if you followed hint2 and got forms authentication working, then you probably want to change the upload tool you're going to write, because you won't like to do manually "for each report browse-directory - check allow override checkbox - upload report - set datasource) for 120 reports or so, then you will be inheriting a class from ReportingService2005 and override GetWebRequest and GetWebResponse
''' <summary>
''' Overriding the method defined in the base class.
''' </summary>
''' <param name="uri"></param>
''' <returns></returns>
Protected Overrides Function GetWebRequest(uri As Uri) As System.Net.WebRequest
Dim request As System.Net.HttpWebRequest
request = DirectCast(System.Net.HttpWebRequest.Create(uri), System.Net.HttpWebRequest)
request.Credentials = MyBase.Credentials
request.CookieContainer = New System.Net.CookieContainer()
If m_authCookie IsNot Nothing Then
request.CookieContainer.Add(m_authCookie)
End If
Return request
End Function ' GetWebRequest
''' <summary>
''' Overriding the method defined in the base class.
''' </summary>
''' <param name="request"></param>
''' <returns></returns>
Protected Overrides Function GetWebResponse(request As System.Net.WebRequest) As System.Net.WebResponse
Dim response As System.Net.WebResponse = MyBase.GetWebResponse(request)
' http://social.msdn.microsoft.com/Forums/sqlserver/en-US/f68c3f2f-c498-4566-8ba4-ffd5070b8f7f/problem-with-ssrs-forms-authentication
Dim cookieName As String = response.Headers("RSAuthenticationHeader")
If cookieName IsNot Nothing Then
m_authCookieName = cookieName
Dim webResponse As System.Net.HttpWebResponse = DirectCast(response, System.Net.HttpWebResponse)
Dim authCookie As System.Net.Cookie = webResponse.Cookies(cookieName)
' Save it for future reference and use.
m_authCookie = authCookie
End If
Return response
End Function ' GetWebResponse
Hint 4: The above methods won't work if you haven't installed service pack 1 + 2 on SSRS 2008 R2...
Hint 5: The TranslateParameters method is there because you cannot (by design) translate the parameter prompts to multiple languages by SSRS, so you write:
Raum / Local / Locale / Room
which uses schema:
Text_DE / Text_FR / Text_IT / Text_EN
And then do split by '/' on the text (which is a little error prone if your prompt text contains '/' somewhere), and then select the right text by index of the language, by choosing MIN(splitarray.length, index) btw, just in case somewhere you only have Text_DE / Text_FR or whatever, first checking if the text contains a '/' at all, of course.
Hint 6:
Need I go on ? (i could still expand this post to tenfold size, but I think I should go back to work now :) )
If you want to see just how f*up it looks, this is how vanilla ssrs renders in chrome
This is what it looks like in IE11, with IE5 compatibility set via xua
And this is what it should be, and what you can get it to render with much tinkering with javascript and CSS
Addendum:
Oh, and it gets even better
If you want to run reportviewer in a language specified by your application (which is NOT identical to the browser language), you need to set the culture of reportviewer to the culture specified in your query string...
<script type="text/C#" runat="server">
protected override void InitializeCulture()
{
string sprache = System.Web.HttpContext.Current.Request.QueryString["in_sprache"];
// System.Web.HttpContext.Current.Response.Write(sprache);
switch(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToLower(sprache))
{
case "fr":
sprache = "fr-CH";
break;
case "it":
sprache = "it-CH";
break;
case "en":
sprache = "en-US";
break;
default:
sprache = "de-CH";
break;
}
// System.Web.HttpContext.Current.Response.Write(sprache);
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(sprache);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(sprache);
base.InitializeCulture();
}
</script>
If you want to set a static culture, you can do so in the page declaration
<%# Page UICulture="de" Culture="de-CH" %>
And if you try to remove the the print icon and the atom-feed, doing it with styles, no matter how, it only works in Chrome...
input[type="image"][title="Drucken"], input[type="image"][title="Print"], input[type="image"][title="Imprimer"], input[type="image"][title="Stampa"]
{
display: none !important;
}
input[type="image"][title="In Datenfeed exportieren"], input[type="image"][title="Exporter vers un flux de données"], input[type="image"][title="Esporta in feed di dati"], input[type="image"][title="Export to Data Feed"]
{
display: none !important;
}
*/
input[type="image"][src$="Microsoft.Reporting.WebForms.Icons.Print.gif"] {
display: none !important;
}
input[type="image"][src$="Microsoft.Reporting.WebForms.Icons.AtomDataFeed.gif"] {
display: none !important;
}
But you can actually remove at least the print icon in internet-explorer by adding ShowPrintButton="false" to the reportviewer control:
<RS:ReportViewerHost ID="ReportViewerControl" ShowPrintButton="false" runat="server" />
Another idea: in SSRS 2012 & 2014 (and possibly 2008R2), you can also add your SSRS-fixing javaScript method into add_pageLoaded of ScriptManager. Like this:
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () { fixReportingServices('rpt-container'); });
Then you don't have to listen to page change events, which speeds things up, because loaded is only called once at the end of each update.
WARNING
Because in the Internet, IE doesn't default to compatibility view,
<meta http-equiv="X-UA-Compatible" content="IE=5">
won't help you with certain issues either (rotate270 text/vertical text).
Even in IE, it only works properly when you are in the intranet, because only then it uses "compatibility view". While the meta-tag sets the brower into IE5-Quirksmode, it doesn't enable "compatibility view", so it isn't the true quirksmode...
MS Report Viewer Control will work fine in IE only.
You can see the Reports from other browsers but you cannot able to view Zoom Option
See the following MSDN articles for browser compabilities and the ReportViewer controls:
Browser Support for ReportViewer Web Server Controls
Browser Support in Reporting Services
I have not noticed any real issue with it being displayed in Firefox or Safari. At times I think it might be getting rendered better in Firefox, but I don't have any actual benchmarks to back that up.
From the hip and perhaps a little stale. ASP.NET used to treat any non IE browser as a box of rocks. May be worth looking into if your experience problems.
http://weblogs.asp.net/fmarguerie/archive/2005/01/04/346222.aspx
SSRS works perfectly on IE6,7,8. It works on Firefox and Safari, but with displaying issues.
There are two possible solutions to fix those, test and see whichever works for you.
Solution 1
Go to
C:\Program Files\Microsoft SQL
Server\MSSQL.(your report server
instance)\Reporting
Services\ReportServer\Pages\reportviewer.aspx
Update style as
<body style="margin: 0px; overflow: auto"> ... <RS:ReportViewerHost style="display:table;" ID="ReportViewerControl" runat="server" />
Solution 2
Add following changes to stylesheet:
.DocMapAndReportFrame { min-height: 660px; min-width: 1280px; }
.MenuBarBkGnd { min-width:1000px; }
Rendering issues exist with Firefox, Chrome and Safari. I know for Firefox and Chrome, there are IE Add-ins that allow you to run the report in a Firefox/Chrome tab.