Archive

Posts Tagged ‘javascript’

Behavior helping cross browser transparency

February 16, 2009 1 comment

One of the things that I hate the most when developing DHTML applications is that I have to write code for at least 3 browsers. And nowadays the differences between them are not so big, but 5 years ago …
If you write some DHTML code you have to consider at least Firefox (>=2), Internet Explorer (>=6) and Safari. These are the most common web browsers. Google Chrome is gaining lately some popularity, but you can assimilate it with Firefox. Opera and other browsers have such a low percentage usage that you can safely ignore them.
Every time you will see some JavaScript code that shows you how to do some tricks, you will probably see a notice that is cross-browser. And if you dig deep inside the code, you will probably see lots of code that does nothing else but testing for the browser and then applying specific code for it.
It would be so nice if all the browsers will implement the standard(W3C) and only the standard. Then you will have an environment by default cross-browser.
A compromise are the existing cross-browser frameworks. But … you have to learn a new framework and you’re stuck with that framework, as your code will not work without it. And, if in the future browsers will become more and more compliant (it’s not a joke, IE8 seems to make small steps in that direction), you are still stuck with that framework.
Nice will be a framework that will ensure the cross-browser thingy in a transparent way.
Let’s be more practical. Some time ago I wrote an article about how you can make HTML elements transparent in a cross-browser way. But you actually had to write code for three browsers. Safari follows the standards here, Firefox >= 1.x as well (we can ignore FF 0.x – nobody is probably using it anymore). So I will focus on a workaround to help you write

element.style.opacity = 0.7;

and to have the desired result even in IE. Let’s admit, IE has always been the “rebel kid”, but also the most used.
The idea is simple. Every time I modify the “opacity” property of an element style in IE, I will run some code to do the necessary translation and ensure the cross-browser in a transparent way.
Now, for this we will use behaviors, an IE specific feature. Which in this case is good, as the code will be ignored by other browsers.
First of all attach a behavior, described in cb-opacity.htc, to all the elements, through CSS code (put it in a STYLE tag or a separate .css file):

* { behavior: url(cb-opacity.htc);}

.
And now the most interesting part – cb-opacity.htc

<PUBLIC:COMPONENT lightWeight="true"> 

<PUBLIC:ATTACH event="onpropertychange" handler="doOnPropertyChange"/>
<PUBLIC:ATTACH event="oncontentready" handler="doOnContentReady"/>

<SCRIPT>
function doOnContentReady() {
    // when this behavior is attached to an element, then check if the opacity was not already set
    // most likely through CSS code
    if (element.currentStyle.opacity != null) {
        element.style.filter = 'alpha(opacity=' + (element.currentStyle.opacity * 100) + ')';
    } else if (element.style.opacity != null) {
        element.style.filter = 'alpha(opacity=' + (element.style.opacity * 100) + ')';
    }    
}

function doOnPropertyChange() {
    // every time the style opacity is changed through JavaScript, then modify the CSS filter too
    if (window.event.propertyName == "style.opacity") {
        element.style.filter = 'alpha(opacity=' + (element.style.opacity * 100) + ')';
    }
}
</SCRIPT>
</PUBLIC:COMPONENT>

And now IE has support for style.opacity. Pretty nice, isn’t it?

Later edit: The same can be applied to cssFloat and styleFloat.

Categories: Web Tags: , ,

!u@#!^$ “Invalid character” IE error

January 28, 2009 16 comments

Internet Explorer is probably the worst browser for web development. Or maybe I’m too used to Firefox.
Let me give you just a simple example, that can drive you mad.
Have you ever encountered the below error?

Line: 2
Char: 1
Error: Invalid character
Code: 0
URL: ... 

I did. So I googled a little bit to see what could be the problem and I come over this article. Of course, that wasn’t the problem. Finally, I realized myself: one of the referenced JavaScript files was missing.

I know that this is my mistake, but I’m totally amazed about the usefulness of the IE error messages. It is a missing file, not an invalid character.
Not to mention, that the URL is always the main one, even though the error occurred in one of the referenced JavaScript files and the line reported is not the actual line where the error occurred, but increased by 1. But this is already common knowledge.

That’s one of the reasons I always use Firefox for web development, try to stick to the standards and only in the end, test the solution on Internet Explorer too. And there is no decent JavaScript debugger for IE. And …

I also wrote a small HTML, for you to see what I’m talking about.

Later update: This was tested on IE6. In IE8 works as expected.

Categories: Web Tags: , ,

Whoami in SharePoint

September 23, 2008 Leave a comment

One of the nicest things in SharePoint is that you can access it not only through the web interface, but through its web services as well. Combining this with AJAX, you can build pretty good user interfaces with a SharePoint backend.
When doing this you’ll definitely be interested in knowing who is currently logged in.
So if you are modifying a SharePoint generated page (like NewForm.aspx, EditForm.aspx or a page associated with a view) and add (D)HTML code to it, you can easily access the _spUserId variable which holds the current logged in user ID in SharePoint.
From this point on if you’re interested in more details you just simply run a query against the user list using SharePoint web services.
If you want to have these information in a page of your own, you can simply run that query using the CAML tag UserID.

<Query>
  <Where>
    <Eq>
      <FieldRef Name="ID"/>
      <Value Type="Integer"><UserID Type="Integer"/></Value>
    </Eq>
  </Where>
</Query<

Just as a note, don’t forget to put Type="Integer" in there.

If you wonder how I got over this, you should read my other article.

Categories: Web Tags: , , ,

JavaScript: keys vs properties

September 20, 2008 1 comment

Maybe some of you are familiar with the concept of map from Java or .Net. What about JavaScript? Do you something similar to this? Almost.
Every object in JavaScript has a set of properties, that can you can access through the [] operator. So, to get a property value: object[propertyName] and to set it: object[propertyName] = propertyValue. And yes, this works for every object ;).
But why almost? Why not exactly like in Java or .Net?
Well, in Java (or .Net) the map is actually a set of pairs (key, value), opposed to JavaScript, where an object has a set of pairs (name, value). You can see that in one case I used key and in the other I used name. Because in Java any object can be a key and in JavaScript only String’s can be.
Confused? Let’s try some examples.
First, let’s create an object and rewrite its toString method:

var key = new Object();
key.toString = function() {
    return "abc";
}

So now alert(a) will actually display “abc”.
And now let’s create another object that we will use it to test the properties on it.

var obj = new Object();
obj["abc"] = 1;
obj[key] = 2;
obj[1] = 3;
obj["1"] = 4;

Probably you’ll be surprised to find out that obj["abc"] returns 2. And this is because the object is first converted to string and then used as the property name. Same for obj[1].
More surprisingly is that this is the case for arrays:

var arr = new Array();
arr["1"] = 4;

Now arr[1] will return 4 and arr.length will return 2, even tough the initial array length was 0.
If you check out the ECMAScript standard, everything is as should be, but still not very intuitive. In my opinion :).

Categories: Web Tags: ,

Web progress bar

September 16, 2008 4 comments

Would you like something like this in your web page?
web progress bar
Then I will show you how to do it.
The basic idea is pretty simple: implement it using 3 DIVs – one for the progress bar background, one for the completed part and one for the label (indicating the completed value or percent). They are stacked on top of each other in the specified order, from bottom to top.

We will have a main DIV, the actual progress bar, and inside it a completed one that will take as much space from its parent as the task is completed and a label to indicate that percentage.

On the main DIV we specify a border that will enclose the entire progress bar and a background that will indicate the remaining part. We also specify a different background on the completed DIV to indicate the completed part of the task. As for the label we specify only a font color and the background should remain transparent, so the label just sits on the progress bar.

Both children DIVs of the progress bar are floated to left and the label one has a negative margin to allow to be displayed at the same coordinates as the completed one.

  • HTML code

    <div id='progressbar' class='progressbar'>
        <div id='completed' class='completed'></div>
        <div id='label' class='label'>0%</div>
    </div>
    

  • CSS

    .progressbar {
        /* only for better layout :) */
        background-color: white;
        border: solid 1px black;
        width: 100px;
        height: 10px;
        font-family: arial;
        font-size: 10px;
    }
    
    .progressbar .completed {
        /* mandatory */
        width: 0%; 
        height: 100%; 
        z-index: 1; 
        float: left;
    
        /* only for better layout :) */
        background-color: navy;
    }
    
    .label {
        /* mandatory */
        width: 100%;
        height: 100%;
        z-index: 2;
        float: left;
    
        /* only for better layout :) */
        text-align: center;
        vertical-align: middle;
        color: yellow;
    }
    

    As you can see some of the CSS properties are mandatory for the component to render as a progress bar, as some of the properties are used only for a visually appealing layout.

  • JavaScript

    function setPercent(percent) {
        document.getElementById("label").innerHTML = percent + "%";
        document.getElementById("label").style.marginLeft = "-" + percent + "%";
        document.getElementById("completed").style.width = percent + "%";
    }
    

Next step will be to wrap all these into a nice component (JavaScript class). But this depends only on your architectural skills, as now you have the basic technique.

And in the end you can see a full working example, tested on IE6, FF3 and Safari 3. If you get rid of the hassle of implementing this yourself and you want a ready to use and easy to integrate progress bar component for your web pages you should see the MyUI JavaScript library. A demo is also available.

Just a side note, a throbber (or indeterminate progress bar) is easier to implement, that one being only a simple animated image.

Cross browser XMLHttpRequest

September 12, 2008 4 comments

AJAX has become more and more widely used. It is a cool thing, you can do a lot with it, but basically (and here is the best part) it is only a new JavaScript object: XMLHttpRequest. There is no need to learn new technologies or languages.
Unfortunately, not all the browsers (please read especially IE) support this in a native and smooth way. If in FF2+ and even IE7, this comes in a native way, in IE6 this comes only as an ActiveX object.
The good news is that, except how the objects are instantiated, everything else is the same.
As I said in FF/Mozilla this comes in a native smooth way


var xmlHttp = new XMLHttpRequest();

but in IE5 and 6, to create it, you actually create an ActiveX object


var xmlHttp = new ActiveXObject("MSXML2.XMLHTTP");

And that’s not all, even the ActiveX object class can be different from Windows version to another, so you might also have:


xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

So every time you want AJAX you might end up with something like this:

    var xmlHttp;
    // use the ActiveX control for IE5.x and IE6
    try {
        xmlHttp = new ActiveXObject("MSXML2.XMLHTTP");
    } catch (othermicrosoft){
        try { 
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } 
        catch (native) {
            // If IE7, Mozilla, Safari, etc: Use native object
            xmlHttp = new XMLHttpRequest();
        } 
    } 

As I’m lazy and I don’t want to write this code every time, I decided to wrap it up in a nice cross browser way.

How? Look at the code below.

try {
    // test to see if XMLHttpRequest is defined
    XMLHttpRequest.DONE;
}
catch (e) {
    XMLHttpRequest = new Object();
    // define also all the constants
    XMLHttpRequest.UNSENT = 0;
    XMLHttpRequest.OPENED = 1;
    XMLHttpRequest.HEADERS_RECEIVED = 2;
    XMLHttpRequest.LOADING = 3;
    XMLHttpRequest.DONE = 4;
}

/** Creates new instance of the XMLHttpRequest object */
XMLHttpRequest.newInstance = function() {
    var xmlHttp = null;
    // use the ActiveX control for IE5.x and IE6
    try {
        xmlHttp = new ActiveXObject("MSXML2.XMLHTTP");
    } catch (othermicrosoft){
        try { 
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } 
        catch (native) {
            // If IE7, Mozilla, Safari, etc: Use native object
            xmlHttp = new XMLHttpRequest();
        } 
    } 

    return xmlHttp;
};

Just to explain a little bit what happens. First we test if the XMLHttpRequest exists, by calling a property on it. If it doesn’t exist, then this will raise an exception and then we will create it. After this, the next step will be to define a method (similar to a static one) to create a new instance and enclose the entire cross browser code. So now we will create a new XMLHttpRequest like this:


var xmlHttp = XMLHttpRequest.newInstance();

Lazy enough for you !? 😉

Categories: Web Tags: , ,

Web Modal Dialogs

March 2, 2008 1 comment

As I highlighted in a previous post, nowadays transparency plays an important role in web pages. And you can do a lot with it, especially regarding visual aspect on web interactive applications. How you can make an element transparent, and more importantly do it cross-browser, I described in my previous post, so please refer to it,as I will not insist on that one anymore.
I will tell you a little trick that will help you improve the look and feel of your web site. If you want a modal dialog in your desktop applications is pretty simple. You will probably think that the things are getting complicated with web pages, but it isn’t so. And this is what I’ll show you how.
First of all, let’s start by simply displaying a dialog. We will simply use for this an absolute positioned DIV, which is much better experience than a browser dialog window (using window.open()).

<DIV id="aDialog">Put whatever content you want in here</DIV>


and the CSS will look like

#aDialog {
    position: absolute;
    z-index: 10;
    width: 400px;
    height: 300px;
    top: 150;
    left: 200;

    background-color: white;
}


This DIV can shown/hidden using JavaScript

document.getElementById("aDialog").style.display = "block" / "none";


But this is not modal as you can still interact with the rest of the page, so let’s make it modal. Much simpler than you think. Just put a div all over the page.

<DIV id="allover"></DIV>


and the CSS …

#allover{
    position: absolute;
    z-index: 5;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;

    background-color: black;
}


So now, everything will be black except your previously created dialog. But probably you won’t exactly like this, but rather everything blurred except your dialog. So the new CSS will be

#allover{
    position: absolute;
    z-index: 5;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;

    background-color: black;
    opacity: 0.5;
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);
    -moz-opacity: 0.5;
}


For more interesting effects you can choose also another background color or even an image. The z-index of the allover DIV should be bigger than the one of the document, but smaller than the one of the dialog. The allover DIV can shown/hidden in the same way as the dialog.
One more thing, before ending this. If you probably tried or just wondering why we need two different DIVs and not simply using only one, the answer is quite simple. If a DIV is transparent, then all its child DIVs are transparent, even tough you modify accordingly the CSS properties.
Hope this trick is useful for you and good luck in creating nice web applications.
And just to see everything working here is an example.

Categories: Web Tags: , ,