Marianne on December 23rd, 2009

to brighten up your day: http://www.youtube.com/watch?v=0b04pKO_698.

Oh, and Merry Christmas and Happy New Year!

Marianne on November 20th, 2009

Hopefully this will save others some time as that, in combination with the previous post, cost me quite a few hours of debugging.

If you are creating a new Dojo widget that includes a JSAPI map, do not put anything above the map or the map will not act as expected (graphics will be placed in the wrong location, zooming doesn’t zoom where it should, etc).

For example, the following widget template acted all funky:
<div>
<div style="text-align: center; padding: 5px 5px 5px 5px;">
<div>${i18nStrings.mapChangeMap}:</div>
<div dojoAttachPoint="divMapSelection"></div>
<div style="padding: 10px 10px 10px 10px;">
<div id="divMap" dojoAttachPoint="divMap" style="width:300px;height:300px;border:1px solid #000;display:block;margin-left:auto;margin-right:auto;"></div>
</div>
</div>

The following widget template worked perfectly:
<div dojoAttachPoint="containerNode" dojoType="dijit.layout.ContentPane">
<div id="divMap" dojoAttachPoint="divMap" style="width:300px;height:300px;border:1px solid #000;display:block;margin-left:auto;margin-right:auto;"></div>
<div style="padding-top:5px;">${i18nStrings.mapChangeMap}:</div>
<select dojoAttachPoint="cboMaps" dojoType="dijit.form.ComboBox"></select>
</div>

Marianne on November 20th, 2009

I’m still working on this one Dojo-based website (not full-time, mind you, I’ve got a few other projects to work on) and noticed that the way I was creating my widgets wasn’t quite right. I used to inherit from dijit._Widget & Dijit._Templated, but noticed that I was getting some unexpected behaviors (see the Show Scrollbars in Widget in TabContainer post, for example). After a lot of trial and error, I did finally figure out how to do it right and get (mostly) expected behaviors. I am now inheriting from dijit.layout.ContentPane (which inherits from dijit._Widget) and dijit.layout._Templated. That did not immediately work with my widget templates, until I realized that the top div in my HTML template needs to have dojoAttachPoint=”containerNode”. Now my scrollbars are showing up when they should, and many of the problems I was having have disappeared. Yea!

Sample HTML Template:
<div dojoAttachPoint="containerNode">
<div dojoAttachPoint="divBallots"></div>
</div></code>

Top of widget:
dojo.provide("Emmster.Widget.Ballots");
dojo.declare("Emmster.Widget.Ballots",[dijit.layout.ContentPane, dijit._Templated],
{
//Specify the path of the HTML file that sets the look of the widget
templatePath: dojo.moduleUrl("IndyVIP", "widget/templates/Ballots.html"),
...});

Marianne on September 24th, 2009

I just had to give some employment information for a proposal and realized that I have over 10 years of experience. When the hell did that happen? Am I that old, really? Sometimes it feels like I graduated college just yesterday…

Marianne on September 23rd, 2009

Visit http://blog.devarchive.net/2008/04/using-region-directive-with-javascript.html for a neat macro you can add to VS to create collapsible regions of JS code. I was myself tempted to just use Aptana to write JS code, but then I’d struggle with my TFS check-ins/check-outs. This makes it a little better!

Marianne on September 18th, 2009

This is going to sound totally geeky, but JS rules! I have never said this about a programming language before (a programming language! What is up with me?), but it’s one the most flexible and powerful programming language I’ve ever worked with. The more I do with it, the more I’m in love!

Marianne on September 17th, 2009

The (Dojo) website I’m designing uses a BorderContainer with the typical top banner, a ContentPane on the left, and a TabContainer on the right. Each tab’s content is a custom widget. My problem was that I was not getting the scrollbars inside the widget’s contents. The solution involved specifying “height:inherit; overflow:scroll; ” in the style of the top div of my widget.

Before adding the style

Before adding the style


After adding the style. Note the scrollbars!

After adding the style. Note the scrollbars!

Marianne on September 2nd, 2009

As I mentioned in my previous post, I’ve started working on a new website. One of the requirements is to be able to switch between English and Spanish. Since I’m using the Dojo framework for this site, I was very interested in Dojo’s Internationalization (i18n) features. Below is a brief summary of how this works:

  • You create a “nls” folder in your site that contains a folder for each language you want to support. In each of these folders, and at the root of the nls folder, you include an identically-named javascript file. This file will just contain a JSON object with key/value pairs that specify the names and values of some text. This is very similar to using a *.resx file in the .NET world.
  • You set the language. I could see two options here (see this for more info):
    • You specify the “locale” in your djConfig setting
    • You use the browser’s default language. This is NOT the language you set in your browser’s Options (this can not be obtained in JS)
  • You set your module path, localization information, etc (see this IBM article for more info)

The problem with this, is that I wanted the user to be able to switch between the languages easily and not be dependent on the browser’s installation settings. I also did not want to have two different sites: one for English, one for Spanish. That just seemed counter-productive.

The internationalization files (those files in the nls folder) are loaded when Dojo is loaded. So once Dojo is loaded, it’s too late to change the language. The solution must then involve setting the language before Dojo is loaded.

I wanted an obvious link on my page that would allow a user to switch between English and Spanish. When the user clicks on that link, the whole page will reload in the new language.

The most obvious way to me to accomplish this was to add a parameter to the URL that would determine the language of the site. The default should be English, but there should be an option to switch to Spanish. So I came up with the following code in the header of my page, before any other files (css or JS) are loaded:

function gup( name ) // from Netlobo.com
{
  name = name.replace(/[\[]/,”\\\[").replace(/[\]]/,”\\\]”);
  var regexS = “[\\?&]“+name+”=([^&#]*)”;
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return “”;
  else
    return results[1];
}
//Get url
var ln = ‘en’;
var languageSetting = gup(‘language’);
if (languageSetting != null && languageSetting == ‘es’) {
  ln = ‘es’;
}
var djConfig = {
  parseOnLoad: true,
  useXDomain: true,
  isDebug: true,
  baseUrl: ‘./’,
  modulePaths: {mySite: ‘js’},
  locale: ln
};

So now I can have a link on my page that points to the Spanish version (http://localhost/mySite/index.html?language=es) or to the English version (http://localhost/mySite/index.html?language=en). If I don’t specify the language parameter, the default language in this case is English (en). Sweet!

Marianne on August 31st, 2009

I’ve just started working on a new website and realized I needed a different height for a specific element of my page. I really didn’t want to do this by code and found this lovely hack:

.headerStyle /*this is for IE*/
{
  background-image:url(../images/headerFadeShort.jpg);
  background-repeat:no-repeat;
  background-color: #000036;
  height:58px;
  background-position:right top;
  left:0px;
}

html>body .headerStyle /*this is for FF*/
{
  background-image:url(../images/headerFadeShort.jpg);
  background-repeat:no-repeat;
  background-color: #000036;
  height:48px;
  background-position:right top;
  left:0px;
}

It’s pretty self-explanatory, but basically, if you specify “html>body” in front of a second identically-named CSS style, it cannot be read by Internet Explorer but can be read by Firefox. Groovy!

Marianne on July 30th, 2009

I’ve been playing with modifying CSS styles on the fly and none of the code I found quite worked in my case. Below is a sample JS function that will return a CSS rule. Tested in FF 3 & IE7. In FF3, if one of your stylesheets is on a different domain, this function won’t bomb out. Just don’t expect to get one of those cross-domain CSS styles back, though!

function getCSSRule(name)
    if (document.styleSheets) {
        for (var ii=0; ii<document.styleSheets.length; ii++) {
            var styleSheet = document.styleSheets[ii];
            var cssRules;
            try {
                if (styleSheet.cssRules) {
                    cssRules = styleSheet.cssRules;
                } else {
                    cssRules = styleSheet.rules;
                }
            } catch(e) {
                console.log(’security error getting css rules’);
            }
            if (cssRules != undefined) {
                for (var jj=0; jj<cssRules.length; jj++) {
                    var cssRule = cssRules[jj];
                    if (cssRule.selectorText.toLowerCase() == name.toLowerCase()) {
                        return cssRule;
                    }
                }
            }
        }
    }
    return null;
}

Additionally, if you are trying to set the width, height, etc of the style, FF is a bit less forgiving than IE. In FF, you need to put the size in quotes and suffix it with “px”. For example:

var myCSS = getCSSRule(‘aCSSStyleName’);
myCSS.style.width = ‘50px’; //This works in both IE & FF
myCSS.style.width = 50; //This only works in IE