Thursday, March 20, 2014

Opening Documents when Using a Dojo TreeGrid

In my last post I referenced some of the styling challenges I faced when using a Dojo Tree Grid.  At the end of this post I will document them so that I would not forget what went into fixing them.  It was also a challenge to figure out who to open documents in a TreeGrid.  Thankfully this challenge was fixed much more easily and quicker than the styling issue.   In this post I will explain how to open documents using a Dojo TreeGrid.

When using a Dojo TreeGrid, you create a Panel that contains the grid.  The code for the grid itself is contained in a Output Script.  There are no extension library controls for the TreeGrid.  You create this in a similar manner to how you would an EXTJS grid.  For a comprehensive blog series on all things Dojo Grid please visit Brad Balassatis' blog

To make the Grid entries clickable, you have to add an event to the Panel that contains the TreeGrid.  This event must be manually added as follows.

1) Go to the All Properties of the Panel
2) Create a new attribute (attrs)
3) Name the attribute "onclick"
4) Enter the value as clientside javascript (more on this below)

The part that is somewhat confusing is that the value must be properly formatted javascript that is static text. If you compute the value then you do NOT have clientside javascript as a choice.  I believe that I found that this only worked when it didn't contain any carriage returns.  

The javascript code I used is as follows:
var grid = dijit.byId('#{id:treeGrid}'); var index = grid.selection.selectedIndex; var item = grid.getItem(index); var unid = item["id"]; var url = "/po/po.nsf/New_PO.xsp?doc=" + unid;if(unid.toString().length == 32){ window.document.location.href = url;}

The first line gets an handle to the grid.  The second line gets a handle to the grid index where your mouse is. The third line is getting the "id" of the row where your mouse is.  The fourth line is building a URL string using the id that you obtained.   

The fifth line is key.  Because each row has an "id", sometimes the id is the category value, and sometimes the id is the UNID of the document in that category.  I had no success trying to change the label of "id", it just breaks the grid.  The if statement checks if "id" is equal to 32, which is the length of a UNID.  If the "id" is not the UNID then it does nothing.  

The last thing I did was to change the pointer to a hand.  I did this by adding a second event attribute to the panel and calling it "onmouseover" and giving it a value of $('#treeGrid').css('cursor', 'pointer');

The only negative here was that the hand cursor is there even for the category rows that do not open.  I also see a potential bug here is you had a category size exactly equal to 32.

The Grid Styling Fix

The styling fix turned out to be that I was not using a theme that extended WebStandard.  Adding WebStandard fixed the styling issue but broke other things.  The fix is to add the dojo.css to your page as the first stylesheet and then also give the containing panel a class of "view-panel".  Thanks again to Brad Balassatis for figuring this out for me.

If your Dojo Tree Grid looks like this then use the fix above to correct the look.

This looks much better

One More Thing

I tried to make a Dojo TreeGrid using a view with two categories but was unable to get it to work.  If anyone knows how to do this, I would love to hear it.

Tuesday, March 11, 2014

How to Load a Different Theme for a Specific XPage

You would think that what I am about to describe would be something that it easy and straightforward but it is certainly not. In the post I am going to go over the two best ways to use a different theme for a specific XPage(s) in your applications.

This post is based on my own experiences, and experiences gained from this Stack Overflow question that I asked.   Thanks to Toby Samples and Tim Tripcony for your answers which are paraphrased below.

The Problem

For whatever reason, whether you are having CSS conflicts or a different reason and you want to use a different theme for a certain page and leave the rest of the application alone.  The assumption here is that you have a theme that you like for the majority of your application.  You have already set that theme in the XSP Properties of the application.

Fix #1

Set the session variable in each XPage to set the theme.  When you set the theme name in the XSP Properties, you are actually setting a session variable called "xsp.theme" that tells the XPages machine what theme to load.  If you want to load a different theme it is a simple fix, just set the variable to another theme.  To make this work, the catch is that you have to set this on every XPage in the application.   The code will look something like this:  context.setSessionProperty("xsp.theme", "alt-theme"); You would place this code in an event in each XPage.  I don't know which event would be the best, but start with BeforeRenderResponse.  The code that you place in the other XPages would set the xsp.theme property back to the name of the primary theme.

Fix #2

Use a complementary NSF to hold the XPage that use the alternative theme.  The fact that the application is split into two NSF's will be seamless to the users.  Tim Tripcony make a compelling argument to the benefits of this approach.  The chief benefit in my opinion is that you leave the rest of your application alone.   This approach seems like the easiest to implement if you are pressed for time.

What Approach did I go with?

I was going to go with Fix#1 but before I got a chance to do that, my friend Brad Balassaitis emailed me that he had figured out why I was have CSS conflicts and how to fix them and thus eliminated my need to use an alternative theme. Thanks again, Brad.