Thursday, November 22, 2007 10:48 PM
zowens
Determine if a user enables JavaScript
I made a post over on my business' blog about the general concept of my post today, determining if a user has JavaScript enabled.
This is sort of a touchy subject since Microsoft has their own AJAX stuff and they pretty much do what they want with that. But what about ASP.NET developers like me that write their own JavaScript? There isn't much support since we can't use their source code. They probably have something in their code that determines if a user has JavaScript enabled. Even if they did, I wouldn't want to put their AJAX DLL in a site in which I don't use ASP.NET AJAX.
So the solution is to check whether the user has it enabled or not and to render stuff based on that finding.
What my solution does is pushes a input control onto a page, changes the value, and does a postback. If the postback gets the data it wants, the SessionState value of the JavaScript key is set to Enabled. I use a WebControl and a helper class to accomplish this. I make use of SessionState since I hate ViewState with a passion :)
Here's the code (in VB):
Helper Class
Imports System.Web
Namespace EagleEnvision.MainSite.Utilities
Public Class JavaScriptDetection
Public Shared Sub SetValue(ByVal isEnabled As Boolean)
If isEnabled Then
SetValue(JavaScriptState.Enabled)
Else
SetValue(JavaScriptState.Disabled)
End If
End Sub
Public Shared Sub SetValue(ByVal state As JavaScriptState)
HttpContext.Current.Session(SessionValue) = state
End Sub
Public Shared Function GetState() As JavaScriptState
Return CType(HttpContext.Current.Session(SessionValue), JavaScriptState)
End Function
Public Shared Function IsEnabled() As Boolean
Select Case GetState()
Case JavaScriptState.Enabled
Return True
Case Else
Return False
End Select
End Function
Public Const SessionValue = "IsJavascriptEnabled"
Public Enum JavaScriptState
Enabled
Disabled
Undefined
End Enum
End Class
End Namespace
Web Control
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports EagleEnvision.MainSite.Utilities.Constants
Imports EagleEnvision.MainSite.Utilities
Namespace EagleEnvision.MainSite.Controls
Public Class DetectJavascript
Inherits WebControl
' generated hidden field properties
Private hiddenID As String = Me.ID + "_jsdetection"
Private value As String = "x"
Private ReadOnly Property DoesNeedValidation() As Boolean
Get
Return (Utilities.JavaScriptDetection.GetState() = JavaScriptDetection.JavaScriptState.Undefined)
End Get
End Property
Protected Overloads Overrides Sub RenderContents(ByVal output As HtmlTextWriter)
If DoesNeedValidation() Then
Dim c As String = "<INPUT type=""hidden"" id=""" + hiddenID + """ name=""" + hiddenID + """ />"
output.Write(c)
Dim script As String = "<script language=""javascript"" type=""text/javascript"">"
script += "document.forms[0]." + hiddenID + ".value = """ + value + """;"
script += "document.forms[0].submit();"
script += "</script>"
output.Write(script)
End If
End Sub
Protected Overloads Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
Dim isEnabled As Boolean = False
If DoesNeedValidation() And Page.IsPostBack() Then
If HttpContext.Current.Request(hiddenID) = value Then
isEnabled = True
End If
JavaScriptDetection.SetValue(isEnabled)
End If
End Sub
End Class
End Namespace
Line needed in the Global.asax
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
JavaScriptDetection.SetValue(JavaScriptDetection.JavaScriptState.Undefined)
End Sub
Here's the code (in C#):
Helper Class
using System.Web;
namespace EagleEnvision.MainSite.Utilities{
public class JavaScriptDetection{
public static void SetValue(bool isEnabled){
if (isEnabled)
SetValue(JavaScriptState.Enabled);
else
SetValue(JavaScriptState.Disabled);
}
public static void SetValue(JavaScriptState state){
HttpContext.Current.Session[SessionValue] = state;
}
public static JavaScriptState GetState(){
return (JavaScriptState)HttpContext.Current.Session[SessionValue];
}
public static bool IsEnabled(){
switch (GetState()) {
case JavaScriptState.Enabled:
return true;
default:
return false;
}
}
public const SessionValue = "IsJavascriptEnabled";
public enum JavaScriptState{
Enabled,
Disabled,
Undefined
}
}
}
Web Control
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using EagleEnvision.MainSite.Utilities.Constants;
using EagleEnvision.MainSite.Utilities;
namespace EagleEnvision.MainSite.Controls{
public class DetectJavascript : WebControl{
private string hiddenID = this.ID + "_jsdetection";
private string myvalue = "x";
private bool DoesNeedValidation {
get { return (Utilities.JavaScriptDetection.GetState() == JavaScriptDetection.JavaScriptState.Undefined); }
}
protected override void RenderContents(HtmlTextWriter output){
if (this.DoesNeedValidation){
string c = "<INPUT type=\"hidden\" id=\"" + hiddenID + "\" name=\"" + hiddenID + "\" />";
output.Write(c);
string script = "<script language=\"javascript\" type=\"text/javascript\">";
script += "document.forms[0]." + hiddenID + ".value = \"" + myvalue + "\";";
script += "document.forms[0].submit();";
script += "</script>";
output.Write(script);
}
}
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
bool isEnabled = false;
if (this.DoesNeedValidation & Page.IsPostBack()){
if (HttpContext.Current.Request[hiddenID] == myvalue)
isEnabled = true;
JavaScriptDetection.SetValue(isEnabled);
}
}
}
}
Line Needed in the Global.asax
void Session_Start(object sender, EventArgs e){
JavaScriptDetection.SetValue(JavaScriptDetection.JavaScriptState.Undefined);
}
This strategy is very useful if you write your own JavaScript using your favorite library (mine is jQuery). Try it out, tell me what you think.
Filed under: .NET, Visual Basic, C#, JavaScript, AJAX, jQuery, ASP.NET