Showing posts for tag "dojo"

A Custom Control for dojox.widget.Toaster

Wed Sep 05 09:27:00 EDT 2012

Tags: xpages dojo

Update: Looks like Chris Toohey beat me to this by a couple months: http://www.dominoguru.com/pages/04092012113950.html

Marky Roden did a presentation at MWLUG that included, among other things, a demonstration of Pines Notify, a jQuery plugin that provides Growl-style notifications - something that could come in tremendously handy in a lot of situations.

I wanted to use something like this, but I decided to check to see if there's an equivalent in Dojo already, so I don't have to start including jQuery as well. Fortunately, there is... ish. dojox.widget.Toaster serves a similar purpose, though it takes its design cues from the little "toaster" notifications common on Windows. However, their default appearance is the worst thing in the entire world:

GAH MY EYES

Fortunately, that can be cleaned up with a little CSS to be a crummy version of Growl:

A little better

With a bit more work and attention to detail, it could end up pretty classy. I think it's still not as featureful as Pines Notify (no "clickthrough" options, its handling of multiple messages with different timeouts is not nuanced, etc.), but it's serviceable.

The API to use this widget is actually pretty straightforward: you run a bit of code at page load to create a toaster object to listen to a specific channel name (e.g. "/save/success") and then publish messages whenever you want something to appear. The code for sending a message is pretty simple, and there are two forms, depending on whether or not you want to include additional parameters:

dojo.publish("/test/channel", ["This is message one, lasting five seconds"])
dojo.publish("/test/channel", [{ message: "This is message two, lasting 10 seconds", duration: 10000 }])

I decided to wrap the instantiation and required resources up into a custom control and make another demo DB:

http://frostillic.us/tests/djToaster.nsf

The "toaster.css" page is the CSS I wrote to override the standard behavior. The margins are intended for the top-right positioning, but could be changed readily to equivalents for other corners.

The control exposes five properties: messageTopic (the channel name, required), defaultType ("message", "error", etc.), duration (in milliseconds), positionDirection (the position and slide direction, defaulting to up from the bottom right), and separator (the text that appears between two simultaneous messages).

Mixing Dojo's BorderContainer with OneUI

Tue Jul 31 21:18:00 EDT 2012

Tags: xpages dojo

Chris Toohey's post earlier today reminded me of a technique I've been using in some of my apps lately. Since most of what I've been doing has been for internal and admin/reporting-type apps, I've been using OneUI extensively - it's straightforward with the Extension Library, looks pretty good, and the consistency of UI works for that type of application.

However, I ran into a problem with large views: putting a very horizontally-large table into the content area of OneUI breaks it horribly, and there's no good fix. With a lot of tweaking, I made it so it at least scrolls and the header extends the full width, but it was still problematic, particularly when I wanted to add a right sidebar.

The solution I ended up going with was to graft the OneUI look onto a Dojo BorderContainer skeleton, since a BorderContainer takes care of overflowing content nicely. The end result works reasonably well:

/tests/oneui-border.nsf

The layout's code is not pretty, but it doesn't have to be. It provides to its children a couple content facets: the primary content area, LeftColumn, RightColumn, and ActionBar, which is pretty much like a Notes client action bar (my project that uses this takes a lot of cues from an existing Notes app). Additionally, it only shows those extra facets when there's something present, so the sidebars and action bar are entirely hidden when not needed. There are a couple caveats, though:

  • It doesn't provide bindings for every property, as Chris Toohey's does. It certainly could - I just haven't had a need for it.
  • Similarly, I don't have a need for the footer area, so that isn't included. However, it easily could be.
  • It needs some stylesheet patching, and the current stylesheet I use has some flaws in non-Safari browsers (I'm still working on it).
  • Since most of the OneUI structure is written out as HTML, it's not as convenient to tweak as the ExtLib's layout control.

Still, it's been working well for my purposes, and perhaps it'll be useful on its own or as a starting point for other projects.

Using dojo.behavior

Tue Jul 03 07:56:00 EDT 2012

Tags: dojo

JavaScript in a browser is a messy business. While you can generally avoid writing a lot of client JavaScript when doing XPages development, it will eventually be necessary to get your hands dirty. While a bit of XSP.openDialog() here and there, things can get hairy when you want to start including the same or similar code everywhere. You can move the code blocks themselves off to a script library, but then you're still stuck including function calls inline.

Enter dojo.behavior. I ran across dojo.behavior when I was looking for a replacement for event:Selectors, which I'd been using for years in my non-XPages web sites to patch up Domino's crummy HTML after the fact. Like event:Selectors, dojo.behavior allows you to write JavaScript blocks that are associated at runtime with elements on the page using CSS-style selectors. Possibly the best way to get an idea for how you can use it is to look at a simple (and, as usual, contrived) example:

dojo.behavior.add({
	"#linksbar a": {
		found: function(a) {
			a.target = "_blank"
		},
		onclick: function(thisEvent) {
			alert("I have been clicked!")
		}
	}
})
dojo.behavior.apply()

As you might suspect from reading it, that code looks for links inside an element with the HTML ID "linksbar" and sets them to open in a new window and, when clicked, display an alert. While you could have easily put both of these directly in the HTML/XPage source, just think about all the other things you'd potentially want to do with client JavaScript: fancy hover actions, custom expand/collapse effects, and any kind of post-render patching. It all adds up, and separating the layout from the JavaScript behavior like this can save a lot of debugging and backtracking headaches.

To actually use dojo.behavior in an XPages app, make sure to include the "dojo.behavior" Dojo module somewhere on your page, either via the XPage or CC's resources or via a theme. Then, create a JavaScript Script Library to house your behavior. I generally start with a skeleton similar to this (with the "body" function just to make sure it's set up correctly):

var DojoBehavior = {
	"body": {
		found: function() { alert("Behavior working") }
	}
}

dojo.ready(function() {
	dojo.behavior.add(DojoBehavior)
	dojo.behavior.apply()
})

Then put your code inside that first "DojoBehavior" object. Finally, include the Script Library in your page or theme and you should be all set.