Hosted By

Contact Me

Misc Links

OpenNTF BlogSphere LotusGeek CoComment Custom Button

Ads by Google

Welcome to keithstric.com!

I hope you find this site useful in some way or another. I strive to bring you all sorts of geeky information and solutions to your most frustrating of issues with the occasional rant on whatever topic, technical reviews and weblog. You'll also find many products that I've developed and make available for you to use however you like. So, grab a cup of coffee, sit down and visit for a while.

Weird SSJS Time/Date stuff...

02/23/2010 3:30 PM By Keith Strickland

While working on the Day view of the XPages Calendar I've kind-of re-arranged the way I'm calculating the different parts of the calendar. Instead of using separate variables for the Month and Year I've setup a date variable which holds a JavaScript date object and then use the getMonth() and getFullYear() functions of the date object. This makes it easier to navigate between the different days and months, you just change that one variable and everything else gets computed from that one date. However, I've come across some weirdness (for lack of a better term) with the getMonth() function that I can't for the life of me figure out.

OK, so I've setup an array with the names of all the months. This is a zero based array because with JavaScript the month numbers are zero based. So, here's what I've got:
sessionScope.put("months", new Array("January","Feburary","March","April","May","June","July","August","September","October","November","December"));
sessionScope.put("dispDate",new Date());
sessionScope.put("dispCalMonth", sessionScope.get("dispDate").getMonth());

Now, the dispCalMonth sessionScope variable contains the correct month, which for Feburary is 1 (remember zero based months). Farther down the form I've got a computed field that uses:
var curMonth = sessionScope.months(sessionScope.get("dispDate").getMonth());
return curMonth;

Now, this is returning 0 (January) instead of 1 (Feburary). I can't figure out why and it's driving me nuts I've even returned just the number instead of the month name, and it does return 0.

Another issue I'm running into is using the setMonth(), setDate() and setFullYear() functions. These don't seem to work at all, at least not on sessionScope variables. I am able to set a new Date variable and use these functions and set the dispDate sessionScope variable to the new date variable. Which while workable, it is rather frustrating

These simple little things are the biggest hold up on Part 4 of the XPages Calendar which will include the day view and hopefully an "Alpha" release to OpenNTF. So, gentle reader, if you've got any ideas on what's going on here, please chime in while I still have a few hairs left.

UPDATE:
OK, in front of the computed field that displays the month is a link. In the onClick event of the link I decrement the dispDate sessionScope variable month. I removed this link and now the month display in the computed field is correct. So, it seems the onClick code is affecting the computed field somehow, so maybe someone can explain that one to me?

UPDATE #2:
OK, after searching the 8.5 Forum I found this post which said he got rid of all the event code and added it back via the source code editor. Well, I tried this with no joy. So, out of desparation I removed all the event code from the link and went and looked at the source. There was still an xp:this.onclick statement in the source and I still experienced the same results I defined above. This tag should not have been where it was, it should have been within the xp:EventHandler and then xp:this.action tags of the source. So I believe this is the whole problem. Now that I know what to look for it should be easy to spot. Also, I think the xp:this.onclick tag gets added if you edit the onclick event from the All properties tab instead of the events section.


SnTT: XPages Calendar Control (Part 3), making it reusable

02/09/2010 1:24 PM By Keith Strickland

In our previous posts we've created a blank calendar and then added some data to it. While this is all well and good, it's not very reusable in it's current state. It's quite dependent on a view being formatted a particular way. What if you already have a view with the data you want to put on the calendar and don't want to change that view? Well, this is what we're going to address today. With these changes the calendar really takes on the form of something useful and not something that only works on your machine.

In this SnTT I will show you how to make your calendar more reusable and we'll also add the framework for some navigation to each cell to open up a day view, week view and month view (the month view may be redundant and I haven't yet decided on if we need to keep it). Also being addressed here is if you want text other than what is in the calendar to show up in the dojo tool tip. As a bonus, we'll also do the blank view with an editable area so you can use your own custom control to display data.

So, with the requirements defined for this session, we're now ready to begin. Looking at the code for the dayCells computed field on the ccCalendar custom control, you'll notice our view name is hard coded along with the column values. This is where the problem lies, we want this to be configurable. We can use "Property Definitions" to address this issue. Property Definitions allow us to define our own properties for a custom control. These get stored in the "compositeData" object(?) and are available for you to use anywhere within that custom control.
Calendar-PropertyDefinition.jpg

Here we need to define some properties for the following:

  • The View Name - lookupViewName - String
  • The Data Column - lookupViewDataCol - Integer
  • The Column that contains the UNID - lookupViewUNIDCol - Integer
  • The Column that contains the Tool Tip text - lookupViewToolTipCol - Integer
  • The text that will used in the lookupViewToolTipCol if no Tool Tip text is available - NoTooltipText - String
You should end up with something like this:
Calendar-PropertiesDone.jpg

Now, open the default XPage, highlight the ccCalendar custom control (it'll be under facets) and fill in the properties we defined. Except here you can use values for your own view instead of the one included in this DB:
Calendar-PropertiesValues.jpg

Once you save and close and view the calendar in the browser, it should look exactly like it did when we left off from Part 2 of the SnTT. The only difference is that the tool tips will now be populated with whatever is in the column defined for the tool tips.

With these changes, the calendar takes on a more useful role, we can now use views we've already designed and just change the properties to match each view. But what if you want to design your own custom control to display data the way you want it displayed? In this case, we can use an Editable Area instead of putting all the data computation within a computed field on the calendar itself. This will allow us to put a custom control onto the editable area on the XPage instead of within the ccCalendar custom control. So, to support this, in the sample database (located in the downloads section) I've added another custom control called ccCalendarEditable. I've modified the dayCells computed field to only spit out the html to begin the column and include the number for the day and start the div which contains all the data for that particular day. We also changed the name of this computed field to beginTD. You'll notice also, that now the day is included within a span instead of a div and also that there is a function call that is within another span. I will get to this shortly.

I added another computed field named endTD which contains the code closing the column and data div.

Now, in between these 2 computed fields I've added an Editable Area and gave it a Name of calData and a Facet Name of calData:
EditableAreaOutline.jpg

When we drag this custom control (ccCalendarEditable) onto a new XPage I think I did find a bug which I discussed in my previous blog entry about being able to drop a custom control onto an editable area which is contained within a repeat. Since this is the case we'll have to hand code the embedding of the custom control I created to contain the data onto the facet within the XPage. This is a simple process and shouldn't cause too much headache. But, I created a new custom control called ccCalData. This control basically contains the code we removed from the dayCells computed field and put into a computed field on the ccCalData custom control. I did it this way to really just show the ability of being able to split up the data and design a little bit more. Also, please forgive my lack of a useful naming convention, since I'm just now really getting started with XPages I haven't really come up with a naming convention I use all the time. But to hand code the embedding of the ccCalData custom control onto the XPage this is the format. Notice the "xp:key" item defines the name of the Editable Area (calData in our case):

So, we now have 2 different ways to make our calendar more reusable. You can use @DbLookups to a view that you've already designed and just change the properties to return the data you want on the calendar or you can design your own custom control to drop onto the calendar. Also, in the case of this sample db the calendar should look at react exactly the same as it did when we left off with part 2. Either way makes this much more useful. Now, in preparation for having a "day view" and "week view" I've added a small drop down menu to allow you to switch views. Read on...


Continue Reading...

XPages question... Editable Area within a Repeat?

02/08/2010 3:05 PM By Keith Strickland

I've been working on making the Calendar Control more of a reusable control rather than using the @DbLookup calls within the ccCalendar control itself. For the most part, I've succeeded in doing this however before I publish it I need some information as it doesn't quite work the way I expect it to.

So, here's the scenario. I've busted the code within the dayCells computed field to only contain the beginning cell HTML, basically the opening TD call. I then added another computed field to handle the closing of the TD. Now, in between these 2 I've placed an editable area. This editable area shows up in the design mode for the ccCalendar Custom Control. Now, when we drag the ccCalendar custom control onto a new XPage, the editable area is visible however you can't drag another custom control onto it. When you try it drops the control above everything else. Also, when you look at the source for the XPage before adding a custom control onto the editable area, there is no xp:this.facets tag. Now I can add this tag manually and define the custom control I created just to display the data and it all works flawlessly but I don't like that I have to hand code it. But below is some screen shots and a short screen cast of the behaviour I'm attempting to describe:

EditableAreaOutline.jpg

Here is the control after I dropped it onto a new XPage. See the Editable Area is available:
EditableAreaDesign.jpg

Here is the entire source of the new XPage, notice there is no xp:this.facets tag:
EditableAreaSource.jpg

Here is the Screen Cast of what happens when you try to drop a custom control onto this editable area:

So, my question is this.... Should you add an Editable area within a repeat? If not, what is a better route?


SnTT: XPages Blank Calendar Control (Part 2), adding data

02/06/2010 11:18 AM By Keith Strickland

The other day I showed you how to make a custom control for an empty calendar. While neat it really isn't very useful unless you can put some data on it. So today's SnTT is to put some data on the calendar. Also, it seems there was a bug in the original code for the month "forward" and "back" links which caused the calendar to do some weird things, but no worries, that has now been fixed and is available in the download.

Now, on adding data. We're not concerning ourselves yet with durations, we'll have to tackle that later down the road and I'm sure I'll have to tap into some people who are smarter than myself. Right now we're only concerned with putting data within the appropriate day, having it formatted correctly and not enlarging the cell to fit the data but instead having a scrollbar available to scroll through the entries. We also want a dojo tooltip to show up when we hover our mouse over an entry so we can see any text that gets cut off. To accomplish this, the contents of a cell are made up of several divs. We use divs so that everything spans the entire width of the cell:

  • A div containing the number which is the day
  • A div containing all the entries for that day
  • A div for each entry
  • A div for the text of a tool tip

With our goal now defined we can start coding a little bit. I created a form called calEnt with just a few fields on it:

  • StartDate (we'll get to the EndDate/Time at some other point in the future)
  • StartTime
  • Subject
I also created a view called luDates with 4 columns:
  • StartDate - Sorted Ascending - This is text and not a date as it seems that the server side javascript @DbLookup can't lookup a date, it must be a string
  • StartTime - Sorted Ascending
  • Subject
  • Unique ID

Now we need to get some data and put it on the calendar. We'll do this in the computed field which we had named in our previous SnTT named "dayCells". To support this we had to add a couple of script libraries, one for Server Side Javascript and another for Client Side Javascript. The functions in the Server Side Javascript Library came from the article Work with DbColumn and DbLookup on the You at Notes website. I had to tweak the requestScope scoped variable check to also include the field (or in our case column) to ensure that there is 2 different requestScope variables. The functions in that library ensure that DbColumn and DbLookup calls are returned as an array, this is quite useful. The Client Side Javascript Library is for a function to handle the onClick event of a calendar entry. I'm not going to go into the code of these functions as they are available in the download.

In the dayCells computed field we start building the table cell with all the divs. Just note you need to change the view name with whatever view name you use in the DbLookupArray calls. You should end up with something like this:

Now we need a form to display our calendar entry in another custom control. This is just a simple form with 4 fields on it. I haven't really made it pretty or anything I just wanted to ensure that it worked, we can make it pretty later. So, I created a custom control with the same fields as the CalEnt form with the exception I added a computed field which contains the UNID of the document we're displaying. This is really just there for troubleshooting purposes but I thought I would list it to show how to get data from a parameter in the URL. I'm passing the UNID of the document we clicked on in the calendar to the URL because since we hand coded the div which contains the data from the view, client side javascript is used to navigate to the "entry" XPage via an onClick event, so we pass the UNID via an URL parameter:

We also need to bind our new custom control to the form. You do this in the Data section of the custom control:
BindAForm.png

And in the document ID field we add our param code again as Server Side Javascript:

You should now have a calendar that has data on it that is clickable which opens up the corresponding document. Next up is configuring our XPage so that the dojo tool tips pop up whenever you hover the mouse over an entry. So, since our calendar control is on the default XPage we need to set some properties here to make the dojo tool tips work. On the default XPage All Properties section of the XPage Properties, set the dojoParseOnLoad = True, dojoTheme = True. Also add a resource and pick dojoModule and for the name set it to dijit.Tooltip. Also under the styleClass property define Tundra as the styleClass. It should look like this:
calendar-dojo-properties.jpeg

And, that's it. You should now end up with this:
calendar-dojo.jpeg

I'm sure there is a better way to handle the binding of data to the calendar, but as I'm really just now starting to really delve into XPages I haven't quite figured out everything I can do yet. So, if you have a better way, please speak up.


SnTT: XPages Blank Calendar Control (Part 1)

02/04/2010 12:41 PM By Keith Strickland

While at LotusPhere I was searching for a way to create a Calendar using XPages to try and duplicate a Calendar View in the Notes Client. As I've said earlier, I believe this was a big part of XPages that was left out or just forgotten about. Well, I finally broke down and tried creating a Calendar Control on my own. Well I can't really say I did it on my own as I used the tutorials over on Declan's site and I had to enlist some help from Declan to solve a problem with the first row of the calendar. So, without further ado, let's get into it shall we...

First I had decided that I wanted to do this with a table instead of spans as it makes sense to do it that way as in my eyes that's what a calendar is, a table. Also I wanted to be able to navigate the months with links at the top of the table and maybe in the future a dojo calendar control somewhere. I've listed all the steps here in the order that I did things, while this may not make sense to some people it's what made sense to me. I guess I probably should've listed these steps in the order that they fall within the code, but I figured it best to go about how I did it. At the end of the article I will include all of the source code so it's just a copy and paste afair.

NOTE: Seems some of the strings within this document in the text areas are being screwed with for some reason. I will place an example DB in the downloads section shortly. Of particular note, the <[CDATA[ tags should read <[![CDATA

So, I started putting this thing together by starting with the Calendar table in a panel with the header and then the starting row of the actual calendar:

Next up is getting the blank cells that will appear when the starting date isn't a Sunday. This requires us to get some information when the page is loaded. We need to know what month, year, the day the 1st falls on and how many days are in the month. We do this with some viewScope variables in the "beforePageLoad" event of the control:

Once the blanks are figured out we just need to start filling in the blank days of the calendar. This is just a computed field inside a repeat function:

Now we need to cycle through the days and place them within a TD and include the day number. There are a couple of things of special note here.

  1. The computed field that adds the closing and opening tags for the rows, this needs to come BEFORE the first entry of the week, NOT AFTER!
  2. In the computed field that puts the day number in the cell, you need to add 1 to the day because the days are zero based. If you don't do this the first will actually read zero
  3. Also, we don't need any logic to figure out the contents of the cell since we're determining if a new row is needed in the first computed field within this repeat

Last part of the calendar table is the blank days after the end of the month when the last day isn't on Saturday and then close the final row of the table. This is accomplished with another repeat control and a computed field:

Finally we need to add a Title Header to the top of the calendar to show the month and then a couple of links to navigate forward and back. This is accomplished using 2 links and a computed field. The month which is displayed in the computed field is determined from the contents of an array which contains all the months and we then use the viewScope.dispCalMonth variable minus 1. The links change the viewScope variables to use the correct date. All of this is placed inside a panel:

Now, to put all of this together:

So, I hope you find this control useful. The next steps (which I haven't quite figured out yet) are to put some data from a view onto the calendar and to add some more functionality to try and match that which is found in a notes calendar view. I am also wanting to put a calendar control somewhere on the page so you can pick a particular date that may be more than a year or so in the past/future.

UPDATE: OK, I think I've got all the formatting stuff fixed. I had to use HTML Encoding on all the items. I'll still put an example db in the downloads section. I also added a screen shot to the read more section.


Continue Reading...

Subscribe to keithstric.com

OpenNTF

Disclaimer

The opinions and ideas posted on keithstric.com are not necessarily the opinions and ideas of my employer. The solutions, techniques and code provided here are not guaranteed or warranted in any way and are free for you to use at your own risk.