05/25/2008

New Dojomino NotesOutline Widget

Category   
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

The dojomino.dijit.NotesOutline is now ready for prime-time. The outline widget allows you to very easily incorporate a Notes Outline on the page from the same or any other database. It is pure javascript (no java applet) based on Dojo's dijit.Tree that issues an AJAX call to the server for the Notes Outline data. It renders icons as they were specified by the Domino Designer and processes the click event for the item into the same page, a new window, or via an onClick event handler of the developer's choosing. It handles multi-level outlines and a demo is available of it here. It has been added to the online demonstration database as well.

It's very simple to add to a page. Like all dojo pages, you add a dojo.require in the header. In this case, dojo.require("dojomino.dijit.NotesOutline"), and then you add a div to the page where you want the outline to appear, such as:

<div id="myOutline" dojoType="dojomino.dijit.NotesOutline" outline="Dojomino"></div>

A shout out to Scott for finding an error in the OutlineStore code which this widget depends upon. Nice to have one caught beforehand for a change. Thanks Scott.

UPDATE: links fixed.

05/16/2008

Date Picker with Calendar Icon

Category   
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

Thanks to Scott's comment on our original Date Picker demo which stated that the principle of affordance means that a Date Picker field should have a visible cue that the field is clickable, we decided that we needed to improve on the basic Date Picker provided by Dojo.

So here's a demo of the Dojomino Date Picker which does just that. An entry has also been added to our Demo database. We've also detailed how we customized the widget on the demo page itself if you want to know what was done.

So thanks for the suggestion Scott and enjoy.

05/16/2008

FilteringSelect Pt 3.

Category   
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 


Ok, so here's a topic I've touched on a couple of times now.  Most recently: http://dojomino.com/dojomino/blog.nsf/d6plinks/DBOS-7BEMA7.  In that post I discussed the creation of a custom widget to properly handle the html output Domino gives us to create a FilteringSelect widget.  With the upgrade to Dojo 1.1 that code no longer worked properly.  So, after a bit of digging around, I found that there'd been some changes in the source for the FilteringSelect widget that needed to be dealt with.

In my previous post, the widget we created was based on the built in FilteringSelect.  To make this work for us, we had to override the postMixInProperties.  In 1.1, things seem to work a bit differently.  I found that the options were now set through a new object called:  dijit.form._ComboBoxDataStore, that is defined in the dijit/form/ComboBox.js file.  So I had to change to override the constructor for that object adding the following:


                for (var x=0; x<root.length; x++) {
                        var tVal=root.options[x].text.replace(/\n/g,'');
                        var vVal=(root.options[x].value=="") ? tVal : root.options[x].value;

                        root.options[x].value=vVal;
                        root.options[x].text=tVal;
                }

That done, everything seems to work fine again.

05/16/2008

Dojo 1.1 and xhrPost

Category    
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 


Some time back I posted (http://dojomino.com/dojomino/blog.nsf/d6plinks/DBOS-79EJ34) about an issue with using xhrPost to submit forms to Domino.  The problem had to do with fields that were created by widgets that didn't have a "name" parameter.  This caused issues as Domino expects all fields to have a name.  I showed a solution that suggested editing the source code to prevent the non-named fields from being submitted.  Recently I updated the application I'm building to use the 1.1 release of Dojo.  I was headed in to make the update to correct for this problem when I noticed that the 1.1 source has been modified to correct for this and I no longer need to add my edit.

My solution to this problem had been to modify this line:
var iq = "input:not([type=file]):not([type=submit]):not([type=image]):not([type=reset]):not([type=button]), select, textarea";

to this
var iq = "input:not([type=file]):not([type=submit]):not([type=image]):not([type=reset]):not([type=button])[name], select, textarea";

This worked just fine.  The fix implemented by the Dojo team (as noted in this bug report http://trac.dojotoolkit.org/ticket/5793) was to change:
_d.query(iq, formNode).filter(function(node){
                        return (!node.disabled);

to
_d.query(iq, formNode).filter(function(node){
                        return !node.disabled && node.name;

So, there's a nice little change that saves us a little trouble.

05/08/2008

Simple Date Picker Demo added to Demonstration db

Category   
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

A quick entry today. We've done date pickers before, but the code's changed since previous Dojo versions. This demo is simple and on target for adding the required HTML attributes to your Notes date field so that you get a dojo date picker control on the web. It also supports validation of required or not required and can handle international date formats.

See the Demo application, or go straight to the Date Picker demo.

05/06/2008

Dojomino 1.1-0 posted with Demo site

Category   
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

Sorry to those of you who've been waiting! We've posted the Developer2008 updated slides and the Dojomino 1.1-0 database in the downloads section as 1 zip file. What does the database contain?
  • The Dojo 1.1 code in the Shared Resources section
  • A cool agent called "Resources Importer" that we use to import all the Dojo code whenever there's a new release. Uses DXL to figure out where to stick files and keeps full folder paths.
  • The current "Beta 0" code for our Dojomino objects (hence the Dojomino 1.1-0 label). These are in the database as Pages for the time being
  • A web interface for exploring the database. Just launch it in a web browser.
  • Demos for using various things. See the Demos view

Not everything is complete on the Dojomino side, and where that is true, we've tried to make note of it. As we continue our development, if we have another update while Dojo is in the 1.1 code stream, then our updated version would be 1.1-1, where we try to keep the Dojo version up front and the Dojomino version following it.

If you're not sure you want to download the database, you can try it out here.

I'd like to thank the core group of people who've helped bring things along to this state. Their efforts and contributions are appreciated.

  • The Dojo team of course
  • David Bockes, Lead Architect at WFS
  • Jason Freis, WFS
  • Michelle Snow, Noblis
  • Breck Young, Veritas
  • Viktor Krantz, eKrantz.com

Please let us know if you encounter problems or have feature requests. We have a number of things cooking right now, including lots more view enhancements with the ever elusive categorized view just around the corner. There's a Show Single Category view capability now, but we don't have a demo of it yet. As soon as we do, we'll post it into the Demos view in the database.

UPDATE: Authentication requirement for demos has been removed. Sorry!

04/28/2008

Coming Soon

Category       
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 


Haven't posted anything in a bit, but that's only partially due to my general laziness.  It's also because I've been diligently working on stuff and have some things to share soon.  In particular we'll have "Filtering Select Part 3" wherein I discuss the changes in Dojo 1.1 that affect the previous discussion on using the Filtering Select with Domino dialog list fields (http://dojomino.com/dojomino/blog.nsf/d6plinks/DBOS-7BEMA7).  1.1 has also brought a change to xhrPost that affects another topic (http://dojomino.com/dojomino/blog.nsf/d6plinks/DBOS-79EJ34) I've covered (in a good way).  I've also been doing more work on Lance's Domino view grid including the addition of searching.  So, I will try to get some info out sooner rather than later on these topics.

02/01/2008

FilteringSelect Pt 2.

Category  
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 


In a previous post (http://dojomino.com/dojomino/blog.nsf/d6plinks/DBOS-7A3TSW) I touched on the subject of using the FilteringSelect with Domino dialog list fields.  That post talked about the format of the html created by Domino as well as an issue with Firefox.  My solution was to have the options for the field provided by a json data store.  Now this works fine but, as I new would happen, I came across a situation where I really didn't want to handle it that way.  So, I decided to see if I could come up with a solution that would allow us to setup the field in Domino that way we normally would and have it just work.

To do this, I started by rooting through the Dojo source code for to find the part that takes the options sent to the browser and convert them for use in the FilteringSelect widget.  I started by looking in the dijit/form/FilteringSelect.js.  I didn't find the code I was looking for there, but found that the FilteringSelect extends "dijit.form.MappedTextBox, dijit.form.ComboBoxMixin".  So I then go into dijit/form/ComboBox.js and review the ComboBoxMixin.  It was there that I found the function "postMixInProperties" function.  This function checks to see if there is a store for this widget already defined.  If not, it creates one from the options for the select box.  The code is:

if(!this.hasDownArrow){
        this.baseClass = "dijitTextBox";
}
if(!this.store){
        // if user didn't specify store, then assume there are option tags
        var items = this.srcNodeRef ? dojo.query("> option", this.srcNodeRef).map(function(node){
                node.style.display="none";
                return { value: node.getAttribute("value"), name: String(node.innerHTML) };
        }) : {};
        this.store = new dojo.data.ItemFileReadStore({data: {identifier:this._getValueField(), items:items}});

        // if there is no value set and there is an option list,
        // set the value to the first value to be consistent with native Select
        if(items && items.length && !this.value){
                // For <select>, IE does not let you set the value attribute of the srcNodeRef (and thus dojo.mixin does not copy it).
                // IE does understand selectedIndex though, which is automatically set by the selected attribute of an option tag
                this.value = items[this.srcNodeRef.selectedIndex != -1 ? this.srcNodeRef.selectedIndex : 0]
                        [this._getValueField()];
        }
}

As we can see, there is a dojo.query lookup for the option tags.  It then goes through them and sets the value and name attributes in the "items" object.  This is then used to create a new data store that is used by the widget.  For our purposes there are a couple of problems that needed to be addressed.  The first is if we don't have a "value" set for our options.  In Domino dialog list field if we don't alias our values then they are sent to the brower as this:

<option>One
<option>Two
<option>Three

No value attribute is set.  To address this I modified this portion of the code:

var items = this.srcNodeRef ? dojo.query("> option", this.srcNodeRef).map(function(node){
        node.style.display="none";
        return { value: node.getAttribute("value"), name: String(node.innerHTML) };
}) : {};

to this:

var items = this.srcNodeRef ? dojo.query("> option", this.srcNodeRef).map(function(node){
        node.style.display="none";
        var fName=String(node.innerHTML).replace(/\n/g,'');
        var fValue=node.getAttribute("value");

        if (fValue==null || fValue=="")
                fValue=fName;

        return { value: fValue, name: fName };
}) : {};

What we do here is check to see if there is a value for the option and if not, set it to be the same as the display text.  We have to check to see if the value is both null or empty because of browser differences.  In Firefox it is returned as null, in IE is comes back as an empty string.

The second problem that I ran into was specific to Firefox.  I had referenced this in my previous post.  My thinking at that time was that FF wasn't dealing with the fact that the option tags weren't being closed.  However, after digging deeper I found that wasn't the issue at all.  Doing a little deeper debugging, I used the console.log function in Dojo to print out the values in the fName and fValue variables.  When I did I got the following:

-In IE-
fValue=One
fName=One
fValue=Two
fName=Two
fValue=Three
fName=Three

-In FF-
fValue=One\n
fName=One\n
fValue=Two\n
fName=Two\n
fValue=Three
fName=Three

Notice that in Firefox we got a newline character "\n" at the end of the first two values, the last value doesn't have this.  IE apparently strips these out.  So to correct, I added the replace on this line:

var fName=String(node.innerHTML).replace(/\n/g,'');

This strips out the newlines and we are golden.  So, at this point I can now use the FilteringSelect widget on Domino dialog list fields and don't have to do anything special to populate the options.  I also no longer need to set the value (the selected option) though the html attributes of the field as I showed in the previous post on this ("dojoType='dijit.form.FilteringSelect' autocomplete='true' store='myKeywordStore' value='" + @If(myField!=""; myField; "Choose One") + "'").

The last thing I needed to do was decided how to get these code changes into my app.  One option would be to change the source code, but I don't like that option as it makes maintenance more difficult.  I have to remember the source changes I made and make sure that future updates don't overwrite them.  So in this case I decided to create my own FilteringSelect widget.  This is a simpler task than it might seem on the surface.  In this case all I really want to do is override a single function.  I created a new js file (stored as a page in my Domino app) called "dojomino/dijit/form/FilteringSelect.js".  The entire code in the file is:

dojo.provide("dojomino.dijit.form.FilteringSelect");
dojo.require("dijit.form.FilteringSelect");

dojo.declare(
        "dojomino.dijit.form.FilteringSelect",
        dijit.form.FilteringSelect,
        {
                postMixInProperties: function(){
                        if(!this.hasDownArrow) {
                                this.baseClass = "dijitTextBox";
                        }
                        if(!this.store) {
                                var items = this.srcNodeRef ? dojo.query("> option", this.srcNodeRef).map(function(node){
                                        node.style.display="none";
                                        var fName=String(node.innerHTML).replace(/\n/g,'');
                                        var fValue=node.getAttribute("value");

                                        if (fValue==null || fValue=="")
                                                fValue=fName;

                                        return { value: fValue, name: fName };
                                }) : {};
                                this.store = new dojo.data.ItemFileReadStore({data: {identifier:this._getValueField(), items:items}});

                                if(items && items.length && !this.value){
                                        this.value = items[this.srcNodeRef.selectedIndex != -1 ? this.srcNodeRef.selectedIndex : 0]
                                                [this._getValueField()];
                                }
                        }

                        dijit.form.MappedTextBox.prototype.postMixInProperties.apply(this, arguments);
                }
        }
);

I needed to include the original FilteringSelect javascript and did so through the dojo.require statement.  In my declaration I told it to inherit from "dijit.form.FilteringSelect".  At this point I found the "postMixInProperties" function in the FilteringSelect source file which was as follows:

postMixInProperties: function(){
                        dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments);
                        dijit.form.MappedTextBox.prototype.postMixInProperties.apply(this, arguments);
                }

The line:

                        dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments);

is what calls the ComboBox postMixInProperties where the code we want to update is.  In this case I simply remove that call with my new version of the code and follow that with the call to the MappedTextBox's postMixInProperties.  That done, everything works as expected.

01/24/2008

Ok, I said it...there will be a set of Dojo-Domino widgets available here in the next few days

Category  
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

I couldn't resist and opened my big mouth at Gurupalooza. We'll publish our beta set of Dojomino widgets, and they will be freely available and open source. They are beta at this point and need a "lotus 2.0" theme which we'll continue to work on. We've been working quietly in the background on the Dojomino view widget for some time and there are a couple of things we want to clean up, but keep your eyes here as we'll be posting something very soon!

01/24/2008

What a huge week for Dojo at Lotusphere

Category     
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

So I'm betting that the vast majority of people in the Lotus community had never heard of Dojo before coming to Lotusphere. After having been here for a week, it's almost impossible for anyone to have NOT heard about it. I'm sitting in the AppDev keynote and Dojo is everywhere. Let's list:

  • Domino 8.5 server: A js library engine will be integrated into the Domino server code (for XPages support) and Dojo will be there
  • Domino 8.5 web: When your Notes forms and views render to the web, Dojo widgets will be available to automatically produce name pickers, calendar widgets, views, etc...
  • Quickr: Dojo's been a part of it since it was released
  • Portal: The ajax components and the widgets that get published have dojo widgets behind many of them
  • Lotus Mashups: IBM's work here is to push standards in OpenAjax Alliance for what a widget, block, flake, gadget should actually be for interoperability...and get everyone working on the same page. But the implementation at the browser level for many of IBM's widgets (for dhtml actions and Ajax communications) is Dojo.
  • Lotus Connections: Not sure whether there's any Dojo running natively in the Connections arena, but there have been lots of demos at Sphere of hooking into the Connections api to pull information from it via dojo/ajax communciations from other environments like LotusMashups, Domino, and Quickr
Welcome to the family Dojo. It's nice to have you on board!