Xomino

Domino with the new improved X

XPages ND9 (Dojo 1.8) does not work with other AMD loaders (and the work around)

Posted by MarkyRoden on May 14, 2013

Today I took a new jQuery plugin that I was playing with from an R8.5.3 environment where it worked, to an R9 environment and it failed – I figured it had something to do with something I had been reading about over the last month and in fixing my problem this lead to a more serious realization that I KNOW other people are also going to come across.

Background

A brief scan of the last month’s discussions on Xpages and jQuery Mobile 1.3 reveals a number of posts started by Dave Leedy regarding the use of IBM Notes Domino 9 and jQuery Mobile 1.3

http://notesin9.com/index.php/2013/04/20/jquery-mobile-seems-incompatible-with-xpages-in-domino-9-0

http://hasselba.ch/blog/?p=1216

http://stackoverflow.com/questions/16058039/jquery-mobile-in-xpages-passing-parameters

http://www.eknori.de/2013-04-21/followup-jquery-mobile-seems-incompatible-with-xpages-in-domino-9-0/

What’s going on?

I saw the following Tip from Sven Hasselbach (very smart man!) on Dave Leedy’s blog post

Looks like an AMD loader problem with Dojo & JQM. I have tried out to disable the Factory scan in a test page and this worked for me. To do this I have added the following parameters in the xsp.properties:

xsp.client.script.dojo.djConfig=dojo-amd-factory-scan: false

Maybe this can help you with your problems in ND9.

This lead me to this bug report

https://bugs.dojotoolkit.org/ticket/15616

make dojo work with other AMD loaders

Which then lead me to the realization that this is a bigger issue than just JQM 1.3 and I solved my problem and here is how.

Solution (ND9)

Within the Package Explorer  (Window—open perspective –> xpages) in the WebContent folder for your database you will find the xsp.properties file (as described http://heidloff.net/home.nsf/dx/06172011015521AMNHE8Y7.htm)

xsp1

Click to open the Source Tab

and enter the following

xsp.client.script.dojo.djConfig=dojo-amd-factory-scan: false

And Save – that’s it

Result

If you look at the source code of the created XPage you will see that the new parameter has been added to the script tab creating the dojo.js as a djConfig property

xsp3

doing a quick search explains what this property does

http://dojotoolkit.org/documentation/tutorials/1.8/dojo_config/

“For example, we could disable the amd factory scan (scanning the module for CommonJS require(module) statements to load as deps) with…”

Not only does that solve the problem with jQuery Mobile, it also solved my problem with the jQuery Table plugin which I wanted to use, which used require.js to load the jQuery dataTable plugin.

GENIUS

thank you Sven Hasselbach (again!)

Posted in dojo, JavaScript, jQuery, R9 | Tagged: , , | 3 Comments »

Server-side HTML vs. JS Widgets vs. Single-Page Web Apps – the XPages version

Posted by MarkyRoden on May 13, 2013

Yesterday I came across this excellent article by Pamela Foxhttp://blog.pamelafox.org/2013/05/frontend-architectures-server-side-html.html. In it she goes through how her company uses all three stated architectures, discusses why, and how they are used by the end users. It struck me as fascinating because I feel like we are going through this exact same struggle in the XPages community – what is the best architecture to create applications for our users? I also feel fortunate to have experienced all three (to an extent) in the past 18 months and I can empathize/understand Pamela’s perspective.

I am writing this blog article to first highlight the original article, but to also put an XPages spin on it and discuss some of the point raised therein. I have been meaning to write on this subject for a while and Pamela’s article said it better than I could because she has real examples to discuss whereas mine was all hypothetical.

Please read the article  before continuing, otherwise the context would be rather lost :)

Server-side HTML (“Web 1.0″)

“This architecture suffers the most in terms of usability – it’s very hard for users to do many interactions in a small amount of time – but it does have definite benefits of easy linkability, shareability, and searchability.”

XPages out of the box is a technology built on this paradigm. The tools provided make it quick and easy to create functional applications based entirely on a request-response constant back and forwards to the server. The bulk of the application logic is based on the server and that is very much akin to traditional Lotus Domino development. XPages does at least move Lotus Domino in the right direction, in that we now have partial refresh and the programmatic ability to execute Server-Side logic without having to completely reload the page.

JS widgets

This is something I really want to get into more. If you look at backbonejs or other JavaScript modelling libraries which model data I think you will see that they have a lot of architectural similarity to Lotus Domino. Flat Data is managed in views(notes document)  models(notes forms) and collections (notes views) except that the bulk of the logic is performed Client-Side. Backbone is based on the premise that REST is the communication medium to get data and update it on the back end. We have REST services in ExtLib and in R9 Data Services out of  the box.

In many senses this is more work than creating a traditional XPages/Notes Domino application because the developer has to code everything by hand – there are no (IBM XPages provided) tools to help develop this architecture.

But the payoff to the end user is significant – the data transfer is as minimal as possible and the transactions with the server are fast – ultimately leading to a faster user interface.

As the application complexity scales, so does the amount of work (and code) necessary to make this happen. This also raises a question about maintainability across an enterprise.

Single-page web apps

With the introduction of the ExtLib Dynamic  Content control Single-page web applications are a real possibility within XPages. The user never has to leave the “XPage” to be able to interact with their entire application. With the controlled use of partial refresh the user can move from View Panel, to Document and back again without having to reload the entire page…ever.

This lead to a very consistent, smart, user interface.

The difference between a corporate web application and a “web-site” become more apparent though as the size and complexity of the application increases.

Twitter is a single-page application – but the overall front end user interface features are relatively limited. Maybe 5-10 different screens and most of those are data reading only – the amount of “update” is limited to posting tweets and profile update.

In a corporate application you could have a significant number of “forms” which require update and an equally heavy number of data views. The complexity for keeping this all on one page does not scale well.

Another consideration is the amount of script libraries etc you have to load when the user first accesses the application. More significant if you have to support older IE browsers or XPiNC which cannot handle dynamic script injection via AJAX. If you have 100 “pages” and only one of them uses a specific plugin (org chart for example) you have to load that script library, regardless of whether or not the user is going to access that page or not. That’s kinda nasty.

So what is best for XPages?

I believe that all development decisions should be grounded in the user experience, not on the easy of development. For too long Lotus Notes has succeeded and then failed by allowing people to build functional applications quickly (cheaply) and then having other people mock it for “working” but looking like crap and/or being too “hard” to use.

That said there is a definite bottom-line balance between the $500,000 application overhaul to code everything in the browser and make an amazing application, and the $100,000 application which works great, is maintainable by the in house development team and if 80% awesome on the end user. The builders of amazing Internet websites do not necessarily have the same restrictions and decision makers as “corporate developers“.

So I think the answer is a balance – if you have a large application broken into 5 functional areas, then why not have a widget or single page like application for each functional area?

The point is that there are many factors which go into designing the application architecture from the ground up – and we *ALL* need to understand the *ALL* options so that we can make the right decision for the customer and end users.

Please – discuss :)

Posted in Just Marky, XPages | Tagged: | 10 Comments »

DCLUG – May 23rd – IBM Sametime Deployment – A look at where are we and where should we go

Posted by MarkyRoden on May 13, 2013

This month we have Maurice Cogdell speaking to us about his recent experiences with Sametime and where it is going in the market.

If you are to attend this meeting YOU MUST use the meetup site (listed below) to state you are attending – name badges will be created prior to the meeting as your access.

Date

23rd May 2013

Address

The meeting will be held at

IBM Technical Exploration Center
401 Greensboro Drive, McLean, VA

Agenda

————————————————————-

11:30am-12:00pm
Networking (lunch provided by IBM)
12:00pm-12:30pm
Welcome
Community Updates
Show and Tell (Group quick shares)
Tip of the month
Announcements for the next meeting

12:30pm – 1:15pm – Presentation

Maurice Cogdell (IBM) - IBM Sametime Deployment – A look at where are we and where should we go

In this session we will take a look at where we are with IBM Sametime, how to get started, and how to successfully deploy the components you require.

IBM Sametime’s modular design allows you many deployment options and complete flexibility. “We will give examples of the key questions that need to be addressed and common responses, that are used to determine which features you want and need…”.

1:15pm-1:30pm
Questions/Answers Networking
1:30pm
END

Please mark the date in your calendar.
If you have any questions please do not hesitate to contact me.

Mark

More information

For more information and to get involved with the DCLUG

http://www.meetup.com/DC-Lotus-Professionals/events/118427022/

Posted in DCLUG, Just Marky | Leave a Comment »

EXTJS in XPages #9 – Infinite scrolling rebooted and reborn – v4.2 BufferedRenderer

Posted by MarkyRoden on May 13, 2013

In this article I will introduce the new EXTJS v4.2 Infinite scroller – the BuffererRenderer. The whole concept of infinite scrolling has been rewritten in the new version of the grid and it had made a huge difference to responsiveness and stability of the infinite grid.

EXTJS in XPages series

Here are links to all of the previous articles in this series

Demonstration

The EXTJS in XPages demonstration database can be found at http://demo.xomino.com/xomino/Extjs.nsf/xBufferedRenderer.xsp

Download

The sample database that will accompany this series is  available from the menu in the live demo database from this link - http://demo.xomino.com/xomino/Extjs.nsf

Introduction

The first thing I suggest you do is go and watch this blog post and video – it explains in WAY more detail that I possibly could how cool the new grid is.

Blog: First Look at Ext JS 4.2 Grid

Video: http://vimeo.com/59611158

And for those of you who couldn’t be bothered the upshot of all of this is that the grids are WAY better than ion 4.2. The synopsis from my perspective is:

  • 10,000 records are loaded into memory and only a fraction of them are displayed in the grid. As soon as a new row is scrolled into view and added to the grid’s DOM model – a previous row is removed. This makes for a small DOM and takes up a finite amount of browser memory.
    • The increase in XPiNC responsiveness is night and day – it is that much better
  • We no longer need remote filtering and sorting
    • thank goodness cos that was a pain and not as flexible as I wanted it to be anyway
  • We can easily take advantage of grouping a large number of records efficiently
  • Selecting multiple documents across the infinite scroller is retained (HUGE DEAL)
  • Grouping is seamless across the infinite scrolling
  • The only downside is that you have to wait for 10,000 records to load from the REST service – and that can be optimized as I have previous discussed
    • This also means we need to be smarter in reloading the grid only when we really need to
    • If it is a 100k download and takes 10 seconds to render – the user will wait the first time but not every time they need to open a document and then come back to the grid because it was not the one they wanted.
  • In some ways Buffered Render is not really an infinite scroller – because it does not go back to the server ever time the user needs to scroll down – it is really just a highly efficient document display modeler I guess.

So how do we make it work

Well there are some changes to our code but not too many and all of these should be familiar concepts based on the rest of the posts in this series so far.

First  we need to load the data into memory – we do this by calling a REST service. We are going to use a different REST service as well. In the previous infinite scroll example we needed the REST service to tell us how many documents there were in the remote store – we do not need that any more as we are going  to load every document in the view. We are going to use a flat JSON ViewService to pull all the documents from the ByFirstName view

The new REST Service

<xe:restService id="byFirstNameFlat" pathInfo="byFirstNameFlat">
	<xe:this.service>
		<xe:viewJsonService defaultColumns="true" count="10000&" viewName="byFirstName">
		</xe:viewJsonService>
	</xe:this.service>
</xe:restService>

Starting the process
The data is loaded in a different way for the bufferedRenderer. Instead of being loaded from a remote service it is loaded from a local data model. That is not a problem for us but means an extra step in the data management process.

The process kicks off in the following manner

Ext.onReady(function(){

	//We are going to pass to the getDataGrid function the url we want
	//and the callback function which we then wants executing once the data is retrieved
	//doing it this way gives us maximum control over what happens to the data
	//and makes the function more generic should we want to use it for other data
	//and other grids in the future

	var url = 'xRestService.xsp/byFirstNameFlat?count=100000',
			theData
	var theCallBack = function(theData){
			createGrid(theData)
			}
	getGridData(url, theCallBack)
});

In this function we “getGridData” and then passing in a callback function we determine what happens after the data is loaded. We are passing in the function variable theCallBack. This allows the getGridData fucntion to execute on what was passed in to it.

I cannot streaa enough how much of a good JavaScript coding practice this is. Instead of hard coding the getGridData function to call the next step in the process – we tell it what to do.
This creates a generic getGridData function which does nothing but that. It can then be used to do anything else we want – because we are able to tell it what to do next.

Check out my article on Make your XPages more maintainable – JavaScript Callback functions for a better understanding on how callback functions work.

function aRandomNumber() {
	return Math.floor(Math.random()*1000001)
}

function getGridData(url, callback){

	var dataURL = url
	$.ajax({
		  url: dataURL+&quot;&amp;rand=&quot;+aRandomNumber()+&quot;&amp;&quot;
		}).done(function ( data ) {
			//one the data is loaded then pass it to the callback function
			//passed in as one of the function arguments
			if(callback){
				callback(data)
			}
		});
}

Loading the data

$.ajax({
	url: 'xRestService.xsp/byFirstNameFlat'
	})
	.done(function ( data ) {
		createGrid2(data)
	});

The grid code has an additional feature for bufferedrenderer. This can either be added as a text string property in the grid or as a feature object of type bufferrenderer. If we do it this second way we have more control over its properties and it separates it from the main grid code.

buffRend = new Ext.grid.plugin.BufferedRenderer( {
        pluginId: 'buff1'
})

The grid
The grid has the renderer as a grid property.

&lt;strong&gt;The store&lt;/strong&gt;
	store = new Ext.data.Store({
		model : 'Person',
		autoLoad: true,
		sorters: {
			        property : 'firstName',
			        direction: 'ASC'
			    },
		id: 'store',
		data: data,
		remoteFilter: false,
		buffered: false,
        proxy: {
            type: 'memory'
        }
	});

The Grid
The grid itself is not that different from the previous examples except for the one critical line - plugins: buffRend

The BufferedRendered is added as a plugin by first defining the Ext.grid.plugin.BufferedRenderer and then adding it as a property to the grid during creation.

 var filters = {
        ftype: 'filters',
        // encode and local configuration options defined previously for easier reuse
        //encode: encode, // json encode the filter query
        local: local   // defaults to false (remote filtering)

	};

buffRend = new Ext.grid.plugin.BufferedRenderer( {
     pluginId: 'buff1'
})

	gridDock = [{
		id: 'activeStorePaging',
	     xtype: 'toolbar',
	     dock: 'bottom',
		 items: [
		   {
		       text: 'Clear Filter Data',
		       handler: function () {
		           grid.filters.clearFilters();
		       }
		   }
	    ]
	 }]

    var grid = Ext.create('Ext.grid.Panel', {
        renderTo: 'gridHere',
        frame: true,
        height: 400,
        title: 'Users',
	plugins: buffRend,
        features: [filters],
        store: store,
        iconCls: 'icon-user',
        columns: [{
            header: 'First',
            sortable: true,
            dataIndex: 'firstname',
            filterable: true
        }, {
            text: 'Last',
            sortable: true,
            dataIndex: 'lastname',
            field: {
                xtype: 'textfield'
            },
            filterable: true
        }, {
            text: 'Address',
            sortable: true,
            dataIndex: 'address',
            field: {
                xtype: 'textfield'
            },
            filterable: true
        }, {
            text: 'City',
            sortable: true,
            dataIndex: 'city',
            field: {
                xtype: 'textfield'
            },
            filterable: true
        },{
            text: 'State',
            width: 80,
            sortable: true,
            dataIndex: 'state',
            field: {
                xtype: 'textfield'
            },
            filterable: true
        }],
        // paging bar on the bottom
        bbar: gridDock
    });

}

Performance
If you watched the video you will see how the improvements in performance are handled. In the example shown in the video they show that for a few thousand records there are hundreds of thousands of DOM elements created for an old flat grid to be scrolled through. Using the new bufferedRenderer there are always the same number loaded – more in the order of 2,000 regardless of the overall data size. This is acheived by programmatically adding an removing the table rows to the visible grid as the user scrolls up and down the grid. If the user can see 25 rows then only 27 rows are loaded. The grid Tbale displaying the data is constantly modified as the user scrolls up and down.

The difference between 4.1.1 and 4.2 is night and day. I don’t just say that lightly. In the latest application we were working on, with 4.1.1 we were seeing a slowdown in XPiNC around 200 documents in the view. With 4.2 we have loaded over 3000 documents without any significant reduction in responsivness and/or speed of the grid.

Night and Day – it is a different application to interact with – quite remarkable!!

Conclusion
Looking at this demo alone on a modern browser you would not really notice much of a difference – but if you compare some of the other examples in XPiNC to this one you will really notice the improvement. That larger the data set the better then improvement.

Posted in EXTJS, EXTJS in XPages, XPages | Tagged: , , | 8 Comments »

Shorthand Conditional JavaScript variable checking using ||

Posted by MarkyRoden on May 5, 2013

In this article I will highlight a shorthand method of JavaScript conditional variable checking. The || operator is commonly recognized as “OR” but it’s usage is broader than some people would think.

You might have occasion to have a variable declaration purposefully override a desired value. In this example the start will be zero unless the start variable has been declared with and assigned value:

Long Hand

var start
/*..bunch o' code..*/
if (!start){
	start = 0
}

Shorter hand

var start
/*..bunch o' code..*/
start= (start) ? start : 0

Shortest Hand

var start
/*..bunch o' code..*/
var start= start || 0

This shorthand use of || can be used anywhere in your code for example, at the end of a function:

var start
/*..bunch o' code..*/
function doStuff(){
	//do some stuff
	return (start || 0) //return start or if that is null/blank/false then zero
}

As a point of reference you might see something like this at the start of an external library which uses Nested Namespacing of object declaration:

var utils = utils || {}

The reason it is done like this is to ensure that the global utils variable is either declared properly as a blank array, or if it already exists it is not over-written.

Posted in JavaScript | Tagged: | Leave a Comment »

jQuery in XPages #19 – Shadow (Add eye catching drop shadows to your page elements)

Posted by MarkyRoden on May 2, 2013

In this article I will describe how to implement and use the jQuery shadow plugin to create great looking shadowed panels within your XPages application.

Demonstration

The XPages integration of shadow is demonstrated here

Download

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

Shadow

Introduction

“Adapted from Nicholas Gallagher’s CSS drop shadows without images demo

Adding “depth” to the visual aspect of your website is one of those things which can make them “pop” (pun intended). Using the shadow plugin, one line of code can be the difference between “meh” and “wow”.

Browser support?

Here’s the nice bit IE9, Firefox 3.5 Chrome, Safari – which means it works in XPiNC as well, and that’s sweet!

shad4

How does it work?

The main driver behind this plugin is really Nicholas Gallagher’s CSS drop shadows without images demo. The plug author just wrapped it as a jQuery plugin to make his and everyone else’s life easier.

Using the plugin could not be easier. Using the normal jQuery selector you identify the design element(s) you want to add a shadow to and then determine which type of shadow to add.

We add the plugin to the WebContent folder within our database and reference it in our source code

<script src="jquery-shadow/jquery.shadow.js"></script>
<link rel="stylesheet" href="jquery-shadow/jquery.shadow.css" />

And then add the code to call the plugin updating the elements with the vpDemo class

   $('.vpDemo').shadow('raised')

Examples
The first example you can see on the website is just a simple view panel. You click the but to. And you can see the effect.

shad1

The second example is an xe:widgetContainer widget from the extension library – this has a dojo stylesheet already applied but the shadow works nicely

shad2

The final example allows you appling it to the xp:panel.

shad3

Other styles

There are other styles  available other than ‘raised’ check out the website demo examples to see the others but be aware that they do not all work in all browsers.

Conclusion

As with most of the plugins in this series – for next to no effort, you get a big payoff in user interface enhancements. In this case even more so because this is all CSS3 and no images necessary.

Just a note

Many people ask me how long it really takes to create the demos and get the functionality into the database.

Well figured this out at 3pm this afternoon, finished work (at 5pm), cooked dinner for the kids, went to a school PTA meeting, put the kids to bed, started writing the blog and finished the demo by 11pm – so not long really :)

Caveat from the author

These are his words on the git hub repo - heed them, or not :)

“The purpose of this is to make it easier, as you don’t need to remember the specific css class names.

However, this is extremely bad practice… and should not be used for a production site, but feel free to use it for prototyping…”

Posted in jQuery, jQuery in XPages, XPages | Tagged: , | 2 Comments »

JavaScript variable hoisting

Posted by MarkyRoden on May 1, 2013

In this article I will give a quick overview of JavaScript hoisting and explain why sometimes your variables are not doing what you expect them to.

In the following example we have a very simple variable declaration and function:

var msg = "hello world"
function sayHi(){
	alert(msg)
}
sayHi()

If you run this through firebug you get the expected message in the browser

js1

However if you change the code slightly you do not get the initially expected response. When you run the following code you get ‘undefined’ as the answer when you would possibly expect to see “hello world”

var msg = "hello world"
function sayHi(){
	alert(msg)
	var msg = "hello galaxy" //<--- new line of code
}
sayHi()

js2
This is due to what is called “JavaScript hoisting” and there is an excellent article on it here - http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html. What is basically happening is that although you did not write it, the function level scoping of var msg = “hello galaxy” is declaring the variable msg at the top of the function before anything else executes.

So what you are really doing is this:

var msg = "hello world"
function sayHi(){
	var msg
	alert(msg)
	msg = "hello galaxy"
}
sayHi()

js3

I recommend you read the article I mentioned and understand how JavaScript scoping differs from other programming languages.

Posted in JavaScript | Tagged: | 5 Comments »

Make your XPages more maintainable – JavaScript Callback functions

Posted by MarkyRoden on April 28, 2013

In this article I will attempt to explain the purpose and benefits of using callback functions in JavaScript.

Introduction

Basic JavaScript functions look like this normally like this

function addMe(a, b){
    return a+ b
}

JavaScript variables normally look like this

var a = 2
var b = 3

Finally we would call the function to add the variables

var theTotal = addMe(a, b)
//5

Seems simple enough

Setting a variable to a function

But we can also combine them into something like this

var totalThis = function(a, b){
    return a+b
}

var theTotal = totalThis(1, 2)
//3

The point of this simple demo is to illustrate that a variable can be “equal” to a function. So that means we can pass it around as a function.

Creating a callback function

Here is an example:

function addMe(a, b, callback){
    var theTotal = a+b
    callback(theTotal)
}

Which is called like this

var theTotal = addMe(1, 2, function(val){
    alert(val)
})

Which returns 3

Walking through that…

  1. We created theTotal variable and made it equal to a function call to addMe
  2. We called the addMe function passing 1, 2 and a function with a value as a parameter
  3. The addMe function received the variables and assigned the name of the incoming function – callback
    1. the incoming function now known as callback was passed a pointer “val” which means it can be called with a parameter later
    2. note there are no () after callback it is the function arguements
  4. The addMe function added theTotal of a+b
  5. the addMe function called the callback function passing a parameter of theTotal
  6. The resulting total was passed back to the addMe function and back to theTotal as 3

Making it optional

If you want to make the callback optional (so it does not have to be called) then all we need to do it test for its existence within the addMe function:

function addMe(a, b, callback){
    var theTotal = a+b
    if (callback){
        callback(theTotal)
    }
}

Some examples of why this makes your JavaScript code better

It is used in external libraries but other JavaScript developers and you will come across it and need to understand it. For example in jQuery, binding an event has been set up to allow “what you want to do after” to be passed in as a callback function. That gives maximum flexibility to the developer wanting to use bind().

$('#foo').bind('click', function() {
  alert('User clicked on "foo."');
});

The most common use would be in AJAX. Being asynchronous the webpage code carries on as if nothing else mattered once the ajax called is made. To get around this, modern JavaScript libraries use callback functions to process the data once the AJAX request is complete. So rather than having more code written after the AJAX call, the code is part of the function call which instantiates the AJAX in the first place. In this example the callback function is in the .done() part of the code which is itself a callback.

$.ajax({
    url: "test.html",
    context: document.body
}).done(function() {
    $(this).addClass("done");
});

And in XPages?

Well if you view the source of your XPage you will see a huge section at the end of the page with a whole load of functions and then a whole load of code which looks like XSP.attatchPartial (for example). That is dojo adding your programmatic events to the webpage onClientLoad as a callback.

For example here is a function

function view__id1__id11__id12__id113__id118_clientSide_onclick(thisEvent) {
    disableWorkingOverlay = true;
}

And here is the attachPartial which only names the function

XSP.attachPartial("view:_id1:_id11:_id12:_id113:_id118", "view:_id1:_id11:_id12:_id113:open",
        null, "onclick", view__id1__id11__id12__id113__id118_clientSide_onclick, 2,
        "view:_id1:_id11:_id12:_id113:myFilesPanel");

Generic Functions

What this really means is the ability to make more optimized (generic) code. If you have a process with 3 steps, you could hard code each step into 3 functions. Say for example

  • getData
  • processData
  • displayData

Well getData seem pretty generic to me and I expect we can use that more than once. So we would make a getData function, to which we would pass either the processData functionality (or) we would pass the necessary function call to take the data and move it to the next processData function. In that way we can use multiple dataSources and control the processing of the data from once central code block rather than having many individual code block for each individual process all over the place.

In the following code example the createGrid function is called as the callback function within the getGridData function. This makes the getGridData function completely generic and reusable. Get me some data and then do this with it.

var url = 'xRestService.xsp/byFirstNameFlat?count=100000', theData

var theCallBack = function(theData){
		createGrid(theData)
		}

getGridData(url, theCallBack)

//getGridData called from the code above
function getGridData(url, callback){

	$.ajax({
		  url: url
		}).done(function ( data ) {
			//one the data is loaded then pass it to the callback function
			//passed in as one of the function arguments
			if(callback){
				callback(data)
			}
		});
}

//createGrid - called from the callback function within getGridData
function createGrid(data){
	etc etc
}

Conclusion

You are going to see callback functions all over the place when you start to look into adding external libraries to your XPages. Don’t be afraid of them. Consider them when creating your XPages functionality – even if it is as an unused options within a function, you never know when you might be glad of that later in the application development.

Posted in JavaScript | Tagged: | 9 Comments »

Webcast: jQuery The World’s Most Popular JavaScript Library Comes to XPages – now on YouTube

Posted by MarkyRoden on April 26, 2013

It was an absolute pleasure to do my jQuery in XPages presentation for the 3rd time (publicly) earlier this week and it was as part of the TLCC and Teamstudio webcast series highlighting some of the people and presentations from the community.

There were 430 people registered for the webcast and at its peak there were over 300 people watching.

As with each presentation, podcast and screencast I have had the privilege of being a part of, I am humbled by knowing that I am able to help other developers and users in the community.

For those people who missed the presentation it was recorded and posted for posterity on youtube

Thank you to everyone who attended and let me know what you want to find out about in the future.

Marky

Posted in jQuery, jQuery in XPages, Just Marky, XPages | 4 Comments »

My first PSC star award – Advise

Posted by MarkyRoden on April 20, 2013

The company I am very proud to work for, PSC Group, has an excellent internal consultant personal growth program called the “5 points of excellence“.

This program allows consultants to grow and learn in 25 different areas from sales, to estimation, to development and others. PSC runs classes to promote individual areas of personal growth such as a consultant bootcamp, rainmaking seminars, personal image classes and many others. I have never worked for a company with such a focused and well defined career development path as this one and I believe it is good for the company and good for me on a personal level.

Earlier this week at the company’s quarterly meeting I was awarded my first star for “Advise”. Advise falls into the “Clients” category along with “Experience, Sell, Oversee and Relate”.

I am very proud to receive my first star after having worked at the company for only 9 months and I look forward to getting more in the near future.

IMG_20130417_205509_586

This star recognizes “becoming a trusted advisor to, and transcending an existing project, for a client” .

:)

Posted in Just Marky, PSC | 7 Comments »