And the gloves are off……

Picture this: I have been away for 5 days and during that time “someone” has been posting cryptic comments on twitter about how the next notesin9 is going to be different….and scaring me.

So I am waiting at the airport this afternoon, about to board my plane home and I get this link from this “friend” who tells me to watch the new video it and enjoy. I download it and watch it on the plane. People start to look at me funny as I start to snort and giggle at my phone.

I am sitting here are 30,000 feet laughing my ass off at the video. Not only at the brutal use of apparently free Child labor, the amazing feminine  likeness of my voice and the awesome lip synching 🙂

The video is of course the latest notesin9 episode 141 and for the record Dave is smarter than he let’s on!

Dave is a good friend and I metaphorically love him to bits – I loved the episode – loved the fact that he took so much time to create it – love the creativity – love the humor / love love love. Thank you I am very flattered.

The gloves are off is a reference I get, something to do with Canadians and this guy called Neal who plays for the Penguins…..I dunno…anyway….

Dave’s overall point is right, horses for courses, the right language for the job and the right job for the customer.

He is right that front end and back end  are 50% equal in importance. The end user doesn’t care about back end and it has 0% importance to them. Your IT manager cares nearly 100% about the back end code and making it maintainable. Who is your customer? 😉

This healthy discussion will go on forever apparently and only serves to demonstrate how complex XPages can be. To IBM’s credit they have created a technology which is equally at home as:

The original and arguably still best secure NoSQL data store who’s primary task is serving JSON to a JavaScript framework such as Angular or backbone

An interoperable, integration platform which provides an application building capabilities with simple drag and drop data controls and a powerful back end data parsing capabilities.

and everything in between.

Love ya Dave 🙂 thanks for the laugh.

I can’t wait to get off the plane and see everyone else’s reaction 🙂

PS
Next time we have a beer I’ll point out the significant errors in your video 😉

When the community comes together we get the right answer

Last week I posted why JavaScript is more critical a skill to learn than Java. There was an outpouring of comments, discussion and responses unlike any I have seen in a while.

To give a little more background as to why I decided to post: I was not to be antagonistic or instigate a storm in a tea cup. It was because for the third time in 2014 I had been told by a notes developer something along the lines of “I can’t learn XPages because I have read that you need to learn Java and I do not have the time/skill to do so”.

For right or wrong the perception gleaned from community blogging was that was Java was required learning, which is not the case. And so I blogged.

What I did not forsee was the outpouring and wealth of knowledge bestowed on my blog comments by more that 20 members of the XPages community. I believe what was created was much much better than the original post alone and is one of the best examples of the community working together to get the *right* information out there.

The comments are unfortunately not the easiest thing to follow as there are so many of them (which is great) so what I will be doing in the near future is putting together a compilation of the sentient parts of the conversation ( ignoring the pointless sarcasm) as a resource for all.

In the mean time I wanted to say thank you one an all who contributed and to let you know I got so much more out of the post then I ever hoped for.

Thanks !!!

Why learning JavaScript is more critical to XPage developers than Java

I have tried to write this article multiple times over the last 2 years, when I read it back to myself it always sounds like I am bitching. Honestly, I usually am and that is why it has not been published. This is a final attempt at a constructive argument against the insistence on many blogs that everyone should learn Java.

Many people think I hate Java; I really don’t. I can program Java (I am no expert admittedly) and have done so on multiple occasions. My concerns are always raised when community members are insistent that everyone should learn Java. I do not believe that to be the case.

Why I believe JavaScript skills are more important to a web developer using XPages than Java.

Since R4.5 Domino has been a web server – and the client side user experience has always been independent of that. The only decision to make them “tightly coupled” was that of the developer who chose to not venture beyond the bounds of the out of the box capabilities.

Just because no-one was championing client side development does not mean that it did not exist. I used IE5 <XML> islands back in 2003, pre-ajax, to make dynamic data loading views. I used jQuery in 2010, long before I experienced XPages. I have always considered myself a web developer. I am sure there are many others who do the same.

Here’s why a long long time ago one of my biggest projects failed. While it exceeded expectations of the customer and absolutely rocked on the server, the end users were never asked if they liked how it looked. It failed because people didn’t like the way it looked and it wasn’t used. It hurt. It really, really hurt. From that project forth I stopped putting the server first.

“Beginner XPage developers need to learn Java / Everyone should learn Java”

I shake my head every time I see this. It is an all out, complete, and utter fallacy. Below are my thoughts on some of the reasons touted for using Java and not SSJS:

  • Speed
    • On low to medium volume document processing the time saving still insignificant compared to network latency and browser rendering speed. I have no numbers on this but in over two years XPages developer and 4 major projects dealing with <50,000 documents in a database. Speed of response from the SSJS code on the server has never been a concern.
    • I recently worked on a database with over 1,000,000 records in it. Accessing and displaying data via SSJS using FTSearch was in the matter of 100s of milliseconds.
    • We have SSJS code getting view entries by key and returning results on 250,000 records in less than 0.5 seconds
    • As has been pointed out in the past, the server caches a large amount of frequently used SSJS code making it no slower than any Java equivalent
    • Java is faster – Yes it is. But in my experience SSJS seems perfectly fast enough.
  • n-tier architecture / Separation of  UI and business logic layers
    • When someone can demonstrate to be that they understand the UI they can lecture me about how they need to separate themselves from it. From my perspective it makes a back end developer’s life easier to separate themselves from the UI they don’t understand.
  • It’s the future
    • I guess that depends on your perspective. If you want to spend the rest of your development career developing WebSphere applications it might be. Either way it absolutely is not necessary for XPages development in the next 2 years
  • Java can do things SSJS can’t
    • Yes I agree, things like Apache POI, custom REST services or Plugin development – absolutely agree.
    • Complex data processing of significant amounts of data (not a normal use-case for a notes database)
    • Use the right tool for the right job 🙂
  • At this stage of the game anyone still resisting a move to XPages is not going to be encouraged by being told they need to learn Java – So please quantify your statements when you tell other community members “they must learn Java”. I think this is more appropriate – “Those of you with a solid understanding of XPages and the JSF lifecycle, who are wishing to take their server side programming skills to the next level, learn Java”
    Beginner XPage developers have enough to learn as it is 
  • Imagine a notes client developer who has never created a web based application before. Which is going to serve them better JavaScript or Java
    AJavaScript – the same language for CSJS and SSJS

I believe XPages web developers (using XPages) need to have a solid understanding of these technologies to be successful – *In this order*

  • Lotus Notes Object Model (assumed)
  • HTML
    • HTML5
  • JavaScript
    • Basic Programming
    • External Libraries (jQuery, dojo)
    • The XSP framework for CSJS JavaScript interaction with the XPages
    • Unique Browser deviations from the ECMA standards (looking at you old IE)
  • CSS
    • Unique browser deviations from the standards
  • XML
  • JSF Lifecycle
  • Other things I have forgetten
  • Java

In Summary: Why is JavaScript more critical to XPage developers than Java?

  • Coding in Java is not necessary to build a web based application (using XPages), JavaScript is.
  • Coding a web browser user interface requires JavaScript and cannot be done in Java
  • JavaScript skills are transferable to *any* web server/client environment, Java much less so.
  • Because no customer ever said “This website looks like crap but the pages load so fast I am in love with it.

I understand everyone has their talents in different areas, but (and I can’t stress this enough), end users don’t care about the technology that makes a website work. End users are more forgiving of a beautiful website which is slightly slow, that a blazing fast, ugly, hard to use site. Ideally it would be beautiful *and* blazing fast but that is a whole separate discussion.

I am not saying using Java is wrong. I just want to temper the expectation that everyone *needs* to learn Java. In my opinion they don’t.

Let the comments blaze on…..

PS
Every time you use a 5 year old IBM XPages out of the box dojo control and tell a customer that it is a good interface, a kitten dies.
Many thanks to Brad Balassaitis for proof-reading and bitchiness reduction assistance 🙂

PATCHing a Document using Domino Data Service

Talk about frustrating – in a week full of slow progress and CORS cross domain hell I found this little annoyance after hours of staring and curing – once again the power of trial and error triumphs over my stupidity again.

The problem

I have a Domino Data Service running on the server and I want to update a document

This is the imaginary URL

https://xomino.com/issues.nsf/api/data/documents/unid/FDCA9C28A793D3F785257C4D0068BBCA

returning the imaginary data just fine

{
    "@href":"\/issues.nsf\/api\/data\/documents\/unid\/FDCA9C28A793D3F785257C4D0068BBCA",
    "@unid":"FDCA9C28A793D3F785257C4D0068BBCA",
    "@noteid":"6EC6",
    "@created":"2013-12-26T19:03:58Z",
    "@modified":"2014-03-23T16:40:10Z",
    "@authors":
    ["CN=Marky"],
    "@form":"question",
    "MIME_Version":"1.0",
    "score":0,
    "answers":1
}

and I am trying up to update it using a simple AJAX call

$.ajax({
  data : {'marky':'newfields'},
  type: 'PATCH',	
  contentType: "application/json", 
  url:'https://xomino.com/issues.nsf/api/data/documents/unid/FDCA9C28A793D3F785257C4D0068BBCA',
  }).done(function(data){
    console.log(data)
  }).error(function(data){
    console.log(data)
  })

Unfortunately I get this big old ugly error….
{
“code”:400,
“text”:”Bad Request”,
“message”:”Error while parsing the JSON content”,
“type”:”text”,
“data”:”com.ibm.domino.services.ServiceException: Error while parsing the JSON content\r\n\tat com.ibm.domino.das.resources.DocumentResource.updateDocumentByUnid(DocumentResource.java:278)\r\n\tat com.ibm.domino.das.resources.DocumentResource.putDocumentByUnid(DocumentResource.java:184)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)\r\n\tat java.lang.reflect.Method.invoke(Method.java:611)\r\n\tat org.apache.wink.server.internal.handlers.InvokeMethodHandler.handleRequest(InvokeMethodHandler.java:63)\r\n\tat

bunch – o – useless Java Stack Trace which never helped anyone…….

com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:306)\r\n\tat com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)\r\nCaused by: com.ibm.commons.util.io.json.JsonException: Error when parsing JSON stream\r\n\tat com.ibm.commons.util.io.json.JsonParser.fromJson(JsonParser.java:86)\r\n\tat com.ibm.domino.das.resources.DocumentResource.updateDocumentByUnid(DocumentResource.java:271)\r\n\t… 65 more\r\nCaused by: com.ibm.commons.util.io.json.parser.ParseException: Encountered \” \”approved \”\” at line 1, column 1.\r\nWas expecting one of:\r\n \”false\” …\r\n \”null\” …\r\n \”true\” …\r\n <INTEGER_LITERAL> …\r\n <FLOATING_POINT_LITERAL> …\r\n <STRING_LITERAL> …\r\n \”{\” …\r\n \”[\” …\r\n \”(\” …\r\n \r\n\tat com.ibm.commons.util.io.json.parser.Json.generateParseException(Json.java:637)\r\n\tat com.ibm.commons.util.io.json.parser.Json.jj_consume_token(Json.java:572)\r\n\tat com.ibm.commons.util.io.json.parser.Json.parseJson(Json.java:409)\r\n\tat com.ibm.commons.util.io.json.JsonParser.fromJson(JsonParser.java:84)\r\n\t… 66 more\r\n”

The solution

So I googled around and I found that the error is caused because the com.ibm.commons.util.io.json.parser is expecting a string as input

http://stackoverflow.com/questions/14254536/is-there-a-way-to-return-a-json-object-within-a-xerestviewcolumn#comment19788635_14254536 – once I found that the solution was simple – send a string and not an object…

$.ajax({
  data : '{"marky":"newfields"}', // Notice this is now a string not an object
  type: 'PATCH',	
  contentType: "application/json", 
  url:'https://xomino.com/issues.nsf/api/data/documents/unid/FDCA9C28A793D3F785257C4D0068BBCA',
  }).done(function(data){
    console.log(data)
  }).error(function(data){
    console.log(data)
  })

PATCHing of a document makes a lot of sense for many reasons – mostly because of reduction in bandwidth – the example code works nicely – but you have to update the web site document to allow the PATCH method.

Be aware that using code like this you are also exposing all your data to having any old fool like me breaking your field based workflow and filling your documents full of crap data if they so chose to.

My suggestion would be to use your own REST service written with your own protections in it 🙂

Once again my stupidity is boundless and as I already discovered on multiple occasions,  JSON is a string and not an object.

 

 

How to add icons to individual items in a Select2 multi-value field

Select2 is one of the best user interface enhancers I have come across – if you do not know what it is then you need to go play with it.

It transforms SELECT boxes into dynamic, stunning, interactive UI elements and allows for all sorts of customizations and developer fun.

What I want to be able to do is select items from different categories within the select2 box and then add an icon displaying to the user which category they came from. In this article I will show how.

Example

I want to take this

s3

turn it into this with a type aheads2

And when a user selects the items – make this based on the category selected

s2

And it is really pretty simple and straightforward.

The Code

We start with our select box

<select style="width:500px" id="vehicle" multiple="multiple">
<optgroup label="Cars">
	<option class="car">Honda</option>
	<option class="car">Toyota</option>
	<option class="car">Ford</option>
	<option class="car">GM</option>
</optgroup>
<optgroup label="Bikes">
	<option class="bike">Harley Davidson</option>
	<option class="bike">Kawasaki</option>
	<option class="bike">Aprilia</option>
	<option class="bike">Ducati</option>
</optgroup>
</select>

and then we add our select2 code

$("#vehicle").select2().on("change", function(e) {
	if (e.added) {
		var icon = ""
		$('.select2-search-choice DIV').filter(function() {
		    icon = '<img src="images/'+e.added.css+'.png"/>&nbsp;';
		    return $(this).text() == e.added.id;
		}).prepend(icon);
      }
})

So what this does is:

  • select the #vehicle DOM element
  • turn it into a Select2 plugin control
  • When the control is changed and if an element is added
  • Find the DIV which has been created to display the new item
    • We use filter based on the newly added.id to make sure we only get the one just created
  • create the HTML for the appropriate icon based on the class of the selected item
  • prepend that icon HTML inside of the DIV containing the newly selected option

Conclusion

I have barely scratched the surface of what is possible with Select2. But I hope that you can see with only 9 lines of code we have significantly improved a user experience 🙂

I love Select2 and the options are endless

Enjoy 🙂

My ongoing struggle with stupidity and what is not valid JSON

So this was a frustrating lesson to learn – and please feel free to be entertained by my apparent stupidity.

I was trying to create my own JSON with an xAgent – seems easy enough. I created a simple output which looked like this

{
    'items': [
        {
            'name': 'AK',
            'dc': 23
        }
    ]
}

and when I fed it through my AJAX code it failed.

$.ajax({
	dataType: 'json',
	url: "http://copper.xomino.com/xomino/ExtjsBigData.nsf/xState.xsp?query="+query
	//url: 'http://copper.xomino.com/xomino/Extjs.nsf/xRestService.xsp/byFirstName?count=5'
}).done(function(data){
	console.log(data)
}).fail(function(e){
	console.log('FAIL')
	console.log(e)
})

But what was interesting is that it returned the data (e) correctly. I was baffled and frustrated for way too long.

So I finally asked he correct question of google (isn’t that always the case) and I found that http://jsonlint.com/ was telling me the strings were incorrect…..

because JSON requires double ” and not single ‘

really?

This worked – changed the single to double quotes.

{
    "items": [
        {
            "name": "AK",
            "dc": 23
        }
    ]
}

and I am apparently now less stupid that I was yesterday…….

PS

Kathy recommends – http://json.parser.online.fr/

jQuery in XPages #20 – NProgress – YouTube-like slim progress bar

In this article I will describe how to implement and use the jQuery NProgress nano scrollbar plugin

Demonstration

The XPages integration of NProgress is demonstrated here

Download

The demonstration database can be downloaded from the link above or from here

NProgress

Introduction

Since Youtube.com added their nano scroll bar at the top of the page there have been a flurry of different jQuery plugins which mimic the nano progress bar at the top of the screen.

np1

The silly thing is that the progress bar itself does nothing useful.

  • It does not
    • Indicate any meaningful progress on the download of the AJAX or page
    • Give any indication of the likelyhood of page download completion
  • It does
    • Give the user a false sense of something happening on the page
    • Provide a nice User Experience for very little overhead and effort on the part of the developer

Using NProgress you can very quickly and easily add this capability to your website for only a very small overhead to the size of your application.

Adding NProgress to your XPages

  • Go to the NProgress site and download the file from the github site linked on the page
  • Drag and drop the contents of the zip file into your WebContents folder
  • Create a sample page with the following
 <link href='nprogress/support/style.css' rel='stylesheet' />
  <link href='nprogress/nprogress.css' rel='stylesheet' />

<xp:this.resources>
	<xp:headTag tagName="script">
		<xp:this.attributes>
			<xp:parameter name="type" value="text/javascript" />
			<xp:parameter name="src" value="js/jquery.js" />
		</xp:this.attributes>
	</xp:headTag>
</xp:this.resources>

<xp:this.resources>
	<xp:headTag tagName="script">
		<xp:this.attributes>
			<xp:parameter name="type" value="text/javascript" />
			<xp:parameter name="src" value="nprogress/nprogress.js" />
		</xp:this.attributes>
	</xp:headTag>
</xp:this.resources>

The reason we add this to our XPage in the manner above is because nprogress uses AMD as a possible loader (to integrate with require.js) and because of that Dojo 1.8 (on an R9 server) breaks it.

On my demo page I have loaded a viewPanel with 1300 documents in it – I cannot show you more because I do not want a large database on my host’s site but rest assured if you run this up to a 5000 row viewPanel the effect is better because the refresh is slower.

np2

On the demo I have included the main example from the NProgress site and you can see that there are a number of methods for starting and manipulating the progress bar. I use start because it very nicely randomly increments itself to give that illusion of progress.

On the XPage I have a button which refreshes the view Panel – and in the client script as the button is pushed I start the NProgress. In the onComplete of the refresh I end NProgress and really it is as simple as that

<xp:button value="Reload  viewPanel" id="button1" styleClass="clickMe btn btn-warning">
	<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="viewwrapper"
		onComplete="NProgress.done()">
		<xp:this.script><![CDATA[
			NProgress.start()
		]]></xp:this.script>
	</xp:eventHandler>
</xp:button>

I would suggest that if you are able to integrate with Tony McGuckin’s excellent XSnippet for intercepting dojo io events you could create an automated NProgress bar should you so chose.

Conclusion

As web developers we have used spinners in our application for quite a number of years – this is a new twist on that concept and seems to be getting very good reviews from users. Consider integrating it into your applications.

Manually Setting Domino Database Properties through DDE

This gets filed under the “I am writing this because I know I am going to forget it, and will need it again”

We had a problem in a database whereby we were checking to see if document locking was enabled and if not then it gets programmatically enabled.

This reference document from IBM tells you how it can be done in LotusScript. This was done to the database which was deployed around the world.

Is there a way to programmatically change Database Properties for a database?

'Set the Allow document locking (LotusScript)
Set docIcon = dbCurrent.GetDocumentByID("FFFF0010")
If(InStr(1,docIcon.~$Flags(0),"5") = 0) then
docIcon.~$Flags = docIcon.~$Flags(0) & 5
End If

So it turns out though that when you write flawed code this can get out of hand add one too many 5s

<item name=’$Flags’><text>fJz47IZ!?nR555555555555</text></item>

What this does is stops the database icon from being updated as it causes a design lock on the element – weird eh.

In Domino Designer in Eclipse (DDE) you can easily fix this through designer.

In the Domino Designer perspective – open Package Explorer and find resources IconNote. Within there you can see the DXL representation of the database properties and you can mess with them to your hearts content.

flag1

You can also get to it through the database properties

flag3

Disclaimer – Don’t mess with Database Properties, brick your database and call me – that’s all your own fault 🙂

Why using XPages Partial Refresh is sometimes easy for developers and bad for users

In this article I will discuss the potential issues of using using a Partial Refresh in XPages and how developer addiction and dependency on it is bad for users.

Introduction

This is the hardest blog post I have written – and I have written and destroyed it about 5 times before this one. Too many times I have come across what I consider to be poor design choices. I am always motivated to write when I am annoyed and rant and whine about how the over use of Partial Refresh is easy for XPages developers and bad for users.

Nathan Freeman’s wrote a remarkably thoughtful and well presented article on performance pro tips and I finally determined to write a constructive, helpful, positive on article on how partial refresh can be used destructively..

This is also written with the hope of triggering a discussion because I have my opinion and I want to find out everyone else’s as well.

The Partial Refresh

part1

Partial refresh is a really powerful addition to the IBM Notes Domino developer’s toolbox. Coming from pre-XPages domino, refreshing a section of the page was always a manual task, you had to be extremely careful to manually retain front-end/back end synchronicity and it was just painful.

With the creation of the partial refresh XPages developers have a new tool which they did not have before – the ability to recompute virtually any section of the page, automagically retaining all field bindings and actually creating a better user experience for the user than the out of the box pre-XPages Domino experience.

Don’t get me wrong and I want to be clear on this, Partial Refresh is a phenomenal addition to Domino development and offers fantastic possibilities to developers.

It also offers the ability to use it as an excuse for poor development techniques and bad architecting of an application

Marky’s Rule of Thumb

“The more DOM elements you have to reload using Partial Refresh, the worse your user’s experience”

Think about it – the more DOM elements you have to refresh the more of this you have to do:

  • Post all necessary field state data to the server to retain all the fields
  • On the server:
    • Traverse through the JSF lifecycle (including nad not in order)
      • recomputing the rendering and loading properties of every control (not just the ones being refreshed)
      • recompute the values of every control (not just the ones being refreshed)
      • recompute all the scoped variables
      • run validation on all fields (unless you use partial execution)
      • Trigger and access any serverside events associated with the controls and which then go through the JSF lifecycle
      • Create the HTML to send back to the server
  • Wait for the download of the returned data to the user
  • Parse the response and then insert it back into the browser’s DOM
  • Trigger all the stages of the dojo ajax model (overall)
  • Give control back to the user

So we shouldn’t use Partial Refresh?

That is not what I am saying – but you absolutely should use it judiciously and sparingly. Better planning and better execution of the XPage application model will provide for a better user experience.

Partial Refresh allows the developer to make potentially bad design decisions which are only at the expense of the end user. Having access to server-side variables at all times is intoxicating and destructive.

** Here’s a perfectly good example: Hiding a field or section based on a separate combobox selection

You have two choices:

  • Use some JavaScript (Dojo or jQuery) and write two or three lines of code. Never leaving the browser client.
    • and if you wanted to be really slick (!should do it!)  then you could use a jQuery .toggleClass() and actually make the transition aesthetically pleasing for the user
  • Send to the user experience to the server, wait for all the necessary DOM elements to re-compute their rendered properties and then send it all back to the user

Your requirement might clearly state that you need to hide a field based on a user’s selection – but the developer has the choice how to execute it. “oo oo oo I can use a Partial Refresh” is not the appropriate answer in every case.

** Another example is: the need to update scoped variables based on a combobox selection

Don’t. Just don’t. Simple

If you are tracking the state of the web browser interface using server-side scoped variables you are doing it wrong. The browser DOM already knows the state of the page – why track it twice and double your code?? Unless you are running a google docs type approach to saving everything on the back end based on the user interaction on the front end, you do not need to keep scoped variables up to date in “real-time” with the user interface.

If you must, must, must update something small (like a scope variable) on the server – use a JSON-RPC service which will send values to the server with the minimum of effort, transport and should not affect the user.

** Final example: Because as a Java developer I must have my n-tier architecture and a full separation of UI and business logic

You know who you are……. 😉

For user experience your XPage is a web based platform and the back end technology you use is irrelevant to the user. Your job is to make their experience the best it can be and not the easiest you can program it. If that means you need to learn something new or involve someone else then you have a duty to your customer to do so.

Deep breath

I don’t really think there is  a perfect rule to determine if Partial Refresh is the right thing to do – but don’t assume it is the only thing you can do. Design decisions should always be considered from the perspective of the user experience 1st and ease of development 2nd, not the other way around.

Server-Side programming is a large part of XPages functionality and will continue to be so. There is nothing wrong with having a significant part of the application logic happen on the server.

User expectations are based around the slick interfaces they see, they couldn’t give two hoots what the back-end architecture is.

Good times to use Partial Refresh

Any time it enhances the user experience.

To recompute field (e.g. selectbox) values when a user exits a decision point on the application workflow (only refreshing the fields you absolutely need to).

It is necessary to use it if you want to create an application using the dynamic content control.

It is necessary if you have any dynamic data bindings happening on the page.

It is a good idea if you have a slow connection and want to keep the initial page size down and only show the users what they need to when they need it.

*insert discussion points here* <—– 🙂

I have intentionally left the last part of this short to garner comments and find out what everyone else thinks

Prototypal inheritance of SSJS across the whole server in XPages

A friend asked me the other day how would I determine where a string lay within a JavaScript Array. I of course answered – “it depends! If you are using newer IE or a non-crappy implementation of the JavaScript engine then use Array.indexOf – it has been around for years…..”

var arr = ["simon", "marky", "david"]
return arr.indexOf("marky") // 1.0

Well – turns out the friend was asking about SSJS in XPages and it turns out that apparently XPages has one of those crappy JavaScript engines of which I spoke and Array.indexOf is not supported (facepalm). (*really??*)

<xp:text escape="true" id="computedField1">
	<xp:this.value><![CDATA[#{javascript:
		var arr = ["simon", "marky", "david"]
		return arr.indexOf("marky")
	}]]></xp:this.value>
</xp:text>

arr1

Polyfill

OK so there is a simple polyfill for the indexOf, which has also been around for years as this article written in 2007 demonstrates…..

if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}

And if we add this to our XPages sample code we get the answer we are expecting….

<xp:text escape="true" id="computedField1">
	<xp:this.value><![CDATA[#{javascript:
		if(!Array.indexOf){
		    Array.prototype.indexOf = function(obj){
		        for(var i=0; i<this.length; i++){
		            if(this[i]==obj){
		                return i;
		            }
		        }
		        return -1;
		    }
		}

		var arr = ["simon", "marky", "david"]
		return arr.indexOf("marky")
	}]]></xp:this.value>
</xp:text>

arr2

Yay !

Prototyping in JavaScript

For a better explanation that I can give, check out this StackOverflow answer on what is prototyping – suffice to say that every JavaScript object has a prototype property and this is the basis for prototypal (as opposed to class based) inheritance in the JavaScript language.

What we did in the polyfill above is: we simply said if Array.indexOf method does not exist, then we created one.

So what does this have to do with XPages?

In JavaScript when you prototype a function, the scope is on the page you are looking at. As soon as you leave the page the prototype is gone. In XPages it seems to be a little broader than that…..

I (unintentionally) discovered that once you prototype the Array.indexOf, not only does it become available on the same page, it is permanently on the same page. You run the prototype code once….then take it away, and it still works. The scope would appear to be at the application level…..

Well so then I asked some people who are way smarter than I and Nathan Freeman pointed me to his article about XPages Performance Pro Tips and told me he expected that the prototype would actually be at the server level and he was right….

I included the URL of the test database in the picture above to demonstrate that when I move the simple code to another database – it still works (after the prototype code has been run once)

rr3

And just to be sure – in another browser !!

arr4

Once the Array.prototype.indexOf was created, it became available in all applications on the server, instantly.

Killing the prototype

  • Restarting HTTP *DOES NOT* stop this.
  • Killing all browsers and starting again does not stop this

As far as I can tell you have modified the way the SSJS works on the server until you kill it. So far I have run a test over 24 hours later and it is still working……

This is COOL right?

Well for one it means that you can seriously enhance all your JavaScript on the server in ways which make custom libraries look like a waste of time. We could truly add all the corporate libraries to SSJS once when the server loads and they would always be available to all developers at all times.

arr5

And the even more awesome (depending on perspective…..)

arr7

Well yeah but…….

You can also serious screw up perfectly good code across the server

arr6

Conclusion

Prototypal inheritance is at the root of JavaScript programming language and is very powerful. What we can see here though is that we are able to affect code across the entire server with a few lines of code. This is *very* cool and *very scary* at the same time.

So with this knowledge comes great responsibility – use it at your own risk and make sure you have very good server side code review if you are going to go down this path.