Thank you everyone for a great 2014 !!!

So my week started off with a question “On a scale of 1 to 10, how would you rate the year professionally?”. It did not take too long to say 10 out of 10. I have achieved pretty much everything I set out to and more. It has been an interesting year personally and professionally. Much change and many new and interesting people to meet.

Having worked for two years at home in Virginia as a remote worked, PSC offered me a new position based out of the main office in Schaumburg IL (just outside of Chicago). The offer was too good to refuse and as soon as school finished in June this summer we moved northwards. My thanks go to John Quirk and the other partners within PSC for having the faith and belief in me that I am worth it.

In Schaumburg I have been able to get closer to “the business” and further away from “core development”. While my day to day role has not significantly changed my outlook on it has. I have happily come to terms with “managing” projects within the Collaboration Practice and after having delivered two year long projects to my main customer, I do not have an significant code contributions to either project. The startling thing is I am perfectly OK with that! I love being a developer and I don’t want to stop. The blogging and research into new areas and fields of interest has kept me happily going throughout the year within project code to work on.

This year, as part of the IBM ICS brand community, I:

  • Presented twice at Connect 2014 in January
    • Worklight (with John Jardin)
    • ExtJS and working with large data in XPages
  • April: Presented a TLCC Webinar – with Jesse and Ulrich –  Speeding up Domino designer and general questions.
  • In August I presented at MWLUG in Grand Rapids, MI
    • Angular.js and XPages
  • In November I found out that my x$ XSnippet was officially incorporated into the latest ExtLib release !!!
  • November I found out that I would be speaking in Orlando again next year with Mark Leusink
  • November I was also very honoured to find out I had been nominated as an IBM ICS Champion for 2015
  • I blogged a total of 78 times (just up from last year) with a hit count of nearly 80,000 (up a full 33% from last year)

Blogging themes

  • The theme for the year I decided was Angular.js. I needed to learn it and understand it as I knew it was going to come into play in our projects.
  • I also wondered into Bluemix in a significant manner and then eventually websockets. With the impending addition of an XPages buildpack into Bluemix I do believe I have a theme for next year (assuming I don’t have a squirrel moment)
  • Along with Bluemix came an excuse to start working with node.js which I had been promising myself for a long time. Websockets is a very good base to start playing with node and its capabilities and there is more of that to come.

So THANK YOU is owed to many people who have made this year such a great one for me.

  • Every person who submitted my nomination as an IBM Champion – I know of at least 6 people who did. I am very flattered and humbled for you to think of me. It is good to have a voice, but encouragement to continue always helps 🙂
  • PSC Group
    • Troy Reimer, Mark Scherer and Toby Samples who have for the most part up with me the entire year on one project or another
    • Kathy Brown and Brad Balassaitis who are just the best Agony Aunts a dont-wanna-be manager could possibly hope to call his friends 🙂
    • Andrew Barickman, who’s mentoring and leadership have taught me a lot this year.
    • John Head who continues to surprise me with his knowledge and understanding. (and bought me the most expensive dinner of the year 😉 )
    • All the new faces I have met at PSC but never really interacted with before, Norm, Dan, Steve, John, Steve, Ken, Shil, Tim, and others.
    • John Bigenwald, for repeatedly reminding me that there are larger egos than mine at the company.
  • David Leedy
    • As much of a pompous fool that man can be, he is still instrumental in me being able to do what I want to socially. I hope it is clear to everyone who knows both of us that David is a very good friend 😉
  • Russ Maher
    • Russ has always been a community supporter and friend, but this year he went above and beyond by inviting my family and I over for July 4th at his house with family. We had only been in the area a few weeks and knew virtually no-one in the area. We didn;t even know where to go for fireworks. His whole family was very welcoming and we were very fortunate to be invited. We regularly drive past his street and my kids go “that’s Mr Russ’ street”. Very significant for them in feeling welcome in a new place. Thank you !!
  • Richard Moy who organized MWLUG and everyone else in the community who organizes a user group
  • Multiple random community members ( I know I will forget some ) who have been fun to interact with and I have learned from this year:
    • Oliver Busse, Nathan Freeman, Jesse Gallagher, Declan (thanks for the drinks) Lynch, Eric (smiley) McCormick, Mark Leusink, John Jardin, Per Lausten, Ryan Baxter, Steve Zavocki, Paul Withers, Brice Elgort, Sven Hasselbach….et al
  • I know developers in at least the following countries – and that makes this all so cool
    • USA, Canada, Brazil, Argentina, England, Ireland, Scotland, France, Germany, Holland, Poland, Switzerland, Belgium, Turkey, Italy, South Africa, Australia, Japan, Denmark, Sweden, Norway and others I am sure

Finally to everyone reading this – I have to admit that a readership of zero would be pretty discouraging and would make me want to find something else to talk about. Thanks for reading and considering this relevant to your day. I hope you enjoy the time with families this New Year and here’s to 2015 !!

 

THANK YOU 🙂

 

Practice what you preach – be fast and look sexy

As people who know me well may have heard once or twice, user experience is everything. When designing a custom web based application for a customer, there is always an unwritten requirement of “look sexy” and be fast.

This week my team and I at PSC successfully rolled out a new global application to a customer and here are some examples of the feedback we received within the first day or so:

  • I tried the new site only this morning and I have only one word: fantastic! It is very user friendly and fast.
  • …not to mention, based on the feedback from partners in the US and leaders across the world, it is the best system they have seen in the company.
  • …thanks for all your efforts! Looks “sexy” so (sponsor) is definitely pleased.

Not a single mention of how the functionality will meet their business needs. Not a thought for how well we have met their requirements. We have done that, but that would be irrelevant if we had delivered a poor looking, slow, but highly functional website.

To achieve the speed we were looking for the application is built primarily on Angular.js and Domino Data. Minimizing the amount of server processing for any given user interaction and minimizing the network traffic necessary to provide the expected response time, was a prime consideration in designing the architecture. Working with the talented design team at PSC and the customer we were able to create a visual user experience which adhered to the company’s strict style guides but looked “sexy”.

Be fast, look sexy, and make users want to tell their friends.

BTE 102: The Future of Web Development Write Once, Run Everywhere with AngularJS and Domino

Mark Leusink and I are very excited to be presenting a session at ConnectED this coming January. This is a great opportunity to come and find out about something a little different from the normal XPages run of the mill development. Mark and I will provide an introduction to the concepts and structure behind Angular.js, and then demonstrate how to build a very simple yet useful application using Angular.js and a Domino data store.

We are also going to blow some minds by showing the same application running on non-Domino platforms. If architected correctly, this transformation can be made with almost no code refactoring at all.

Come and see us in Orlando !

http://www.ibm.com/software/collaboration/events/connected/

Marky, Mark

 

Track: Beyond the Everyday

Abstract

AngularJS is currently the most popular JavaScript MVC framework. It’s driving more adoption and interest in the MVC/ REST API application architecture model. The ease of use, portability and re-usability of the code makes it an ideal solution for modern web developer needs. We’ll show you how to use AngularJS to modernize your existing Domino apps, while leveraging Domino’s best features. The speakers will also demonstrate how the power of architecting a solution based on AngularJS allows your Domino application to be made available through other platform interfaces. Taking “Write once, run everywhere” in the literal sense, you will see the same Angular/ Domino based app running natively in XPages, IBM Connections, Bluemix, IBM Worklight and more. Client-side JavaScript frameworks such as AngularJS are the future of web development – come and see it in action. 

Angular in XPages: Formatting Domino Data Services Date values with app.filter

In this article I will show how we can use the core angular date filter capabilities to format Date format, Domino data into an Angular.js based application

Introduction

In previous articles I have shown how to create a simple Angular.js application using a notes Domino Data Services feed from a notes database. If we want to add “date” information then we need a way to nicely format it. Using the Angular.js documentation page as reference I will show you how we can do this with Domino data.

Adding dates to our view

When we add a date field to a Domino Data Services feed we get something which is to the human eye pretty “ugly”

a1

And when we add lastModified into our template, it is well, less than appealing….

a2

 

Adding a formatting function to the template

We can modify the template to use a formatting function by changing up the template slightly and then adding a formatting filter to the application.

In the app.js we add the following

personApp.filter("formatDate", function () {
    return function (x) {
        return new Date(x);
    };
});

And then we reformat the template as such:

    <tr ng-repeat="person in people"  on-last-repeat>
        <td>{{person.firstname}}</td>
        <td>{{person.lastname}}</td>
        <td class="zipCode">{{person.zip}}</td>
        <td class="user">{{person.username}}</td>
        <td class="user">{{person.lastModified | formatDate | date:"dd MMM yyyy" }}</td>
        <td><a class="btn btn-info" href="#/person/{{person['@unid']}}">Edit</a></td>
        <td><a class="btn btn-warning" href="#/person/{{person['@unid']}}/delete">Delete</a></td>
    </tr>

The critical part is {{person.lastModified | formatDate | date:”dd MMM yyyy” }}.

The documentation unfortunately is not clear on this and I found this Stackoverflow example which worked perfectly. http://stackoverflow.com/a/25856275/1171653

The resulting page now looks formatted and much easier to read

a3

Conclusion

I spent which a lot of time failing to achieve this date formatting without doing it the angular way. One quick google (or three) and I had the answer. Do it the angular way and oo look that that nice and simple formatting.

Looking forward to IBM ConnectED – AD201: IBM Domino Applications in Bluemix

The session preview tool for ConnectED 2015 has been announced.

https://www-950.ibm.com/events/global/ibmced/agenda/preview.html

Looking through it I found the following abstract – which unsurprisingly has me really excited !!!

AD201: IBM Domino Applications in Bluemix

This session will show how Bluemix enables you to deploy Domino applications to the cloud in a matter of minutes. We will demonstrate how to leverage Bluemix buildpacks like XPages and Node.js both to modernize Domino applications and to give them a new home on a highly scalable and resilient PaaS. You will learn how to mix and match Bluemix runtimes and services to create Domino cloud apps rapidly, stage them privately and put them into production. You’ll see how to use cutting edge tooling to monitor and manage your apps. This is the future.

Presented by the XPages boys themselves – Martin Donnelly and Tony McGuckin

From Martin on Twitter –  “@MarkyRoden: it will be both me and @tonymcguckin presenting. Glad it’s caught your interest – should be lots of new stuff to see here :-)”

This is what I have been hoping for since it was announced that IBM were “investigating it” at MWLUG back in August 2014.

XPages buildpacks, mix and match run times – I might just be in developer heaven if this is as good as it sounds !!!

Save me a front seat I will be there !!!!

Websockets in XPages: Improving on the automated partialRefresh interface

In this article I will further discuss how tom improve the user experience of an automated partial Refresh on an user’s XPage. Although these posts were originally about using Bluemix to host the node.js server I kinda feel that the focus has drifted onto websockets more than Bluemix. So in an attempt to make it easier to find I am going to use the Websockets in XPages title moniker for a few posts and then go back to Bluemix 🙂

Introduction

In the last article we looked at how to push a automated partialRefresh to a XPage application using websockets. In that article it was noted that the user experience was not ideal because the whole panel refreshed without the user knowing about it. For some apps that is appropriate and for others it may not be. At this point in his career Dave Leedy is impressed he gave someone else and idea and I quote: “wow! that’s fricken awesome!!!”

So, that’s not a great user experience – what if they were doing something at the time?

Yes I was thinking that too! So I believe we can improve the user experience a little and take what Dave suggested and tweak it a little. Now where have a seen something which let’s the user know there is new data changes but doesn’t refresh the page without their action……….

b4

oh yeah that.

Instead of refreshing the control automatically, we will make the message create a “refresh” icon on the page which the user can then update at their leisure.

b5

The modified code is all in what happens when the page receives the refresh socket message. I added a jQuery rotate function just for some added “je ne sais quoi“. In the function we can see that when the refresh event is detected by the socket code the refreshControl function is called. This in turn makes the hidden refreshIcon visible, adds an onClick event and then rotates it. The onClick event performed the partialRefreshGet as we saw in the previous example turning the page briefly grey. We then hide the icon and remove the click event (to avoid piling on multiple events as the page gets continually refreshed)

 

 // Function to add a message to the page
  var refreshControl = function(data) {

	  $('.refreshIcon')
	  	.css({display: 'block'})
	  	.on('click', function(){
	  	   var temp = $('[id*='+data.refreshId+']').css({background: '#CCCCCC', color: 'white'}).attr('id')
		   XSP.partialRefreshGet(temp, {})
		   $(this).css({display: 'none'}).off('click')
	  	})
	  	.rotate({
	      angle:0,
	      animateTo:360,
	      easing: function (x,t,b,c,d){        // t: current time, b: begInnIng value, c: change In value, d: duration
	          return c*(t/d)+b;
	      }
	   })
  };

  // When a refresh message is received from the server
  // action it
  socket.on('refresh', function(data) { refreshControl(data); });

The following video quickly demonstrates the new capability.

Conclusion

In this brief article we concentrated on how to improve a user experience by notifying them that changes were pending and then allowing them to determine when the changes were made.

I still don’t think this is as optimal as I would like but you get the idea. As I said a long time ago – the more DOM you are reloading the worse the user experience. With a viewPanel we are kinda limited on what we can and cannot refresh. A better option may be to architect the application just the new data and update as appropriate……….

 

XPages and Bluemix: Pushing out data changes through automated partialRefresh

In this article I will demonstrate how using targeted websockets messages we are able to refresh user data on pertinent screens within an application, and keep user’s data up to date.

Introduction

In previous articles I have discussed the creation of a nodejs websockets service within Bluemix and how we are able to send messages to specific web pages using the socket.io rooms capability. Both of those examples were proofs of concept and the messages were generated in the browser via firebug console commands. We are going to look at how we can automate these messages and begin to build a user case for using websockets within our applications.

Disclaimer: This idea for an example was the brainchild of David Leedy and in many ways it is a genius example to relate websockets to XPages functionality. And at the same time, I am absolutely disgusted that I am even talking about this because I would never dream of actually implementing this within an application. The fact that the page changes without the user’s knowledge is poor, and the fact that it refreshes the entire control when only a small piece of data changes is horrible. All that said however, this is still a demonstration of the capability and in future blog posts on the subject I will actually show example which I would be proud to actually put into one of my own applications 😉

Keeping data up to data on an XPage

Let’s say we have a sample application with a simple XPages viewPanel on it

b1

Somewhere within the application – someone else makes a change to the data

b2

The only way to see the change would be to refresh the page – and you the user would never know when.

b3

This can be pseudo-automated from a user experience perspective in a number of ways but they all involve periodic checking for updates on way or another. If you scale that over many users this is extremely inefficient.

That is where websockets comes in very nicely.

Pushing to specific rooms

In the previous article I demonstrated how to record an XPage as a “room” dynamically and in this example we will do the same thing.

  var temp = (location.href.indexOf('copper.xomino.com')>0) ? "http://localhost:3000" : 'http://xominosocket.mybluemix.net'
  var socket = io.connect(temp)

  // Send message to server that user has joined
  nickname=$('.username').text()
  var xpageName = location.href.split('.nsf/')[1]
  xpageName = xpageName.split('.xsp')[0]
  socket.emit('joinRoom', xpageName, nickname);

Automating a partialRefresh

In a similar manner to listening for a new chat message and then acting upon it, we are going to listen for a “refresh” socket event and then action it. In this case we are also going to pass in the id of the XSP control we want to refresh. For the sake of this example I am also using some CSS to make the element appear momentarily grey (see the video and all will be clear)

  // Function to add a message to the page
  var refreshControl = function(data) {
	  //Get the refreshId from the incoming data and color the control grey
	  //then get the id of the element via the is attribute
	  var temp = $('[id*='+data.refreshId+']').css({background: '#CCCCCC', color: 'white'}).attr('id')
	  //With the known id - trigger a XPages partial refresh of the control
	  XSP.partialRefreshGet(temp, {})
  };

  // When a refresh message is received from the server
  // action it by calling the refreshControl function
  socket.on('refresh', function(data) { refreshControl(data); });

Creating a new listener on the node.js server

I created a new route to post my refresh data to “xpagesRefresh”. When data is POSTed at xpagesRefresh it is parsed and send back out via websockets using the “refresh” socket event.

// Handle the form POST containing the name and , reply with the language
app.post('/xpagesRefresh', cors(corsOptions), function(req, res){
  var request_data = {};

  if (req.body){
    request_data = {
      'refreshId': req.body.refreshId,
      'nickname': req.body.nickname,
      'rt': 'text'
    };
  }

  var data = { refreshId: request_data.refreshId, nickname: request_data.nickname};
  console.log("POSTing at xpagesRrefresh")
  console.log(req.body)

  io.sockets.emit("refresh", data);
  res.send(data);
});

Automating the partial refresh via the user action

In a real application we are not going to have someone sitting on a browser pushing updates via firebug. We want to be able to create the update when the XPage is saved in the first place. To do this we transfer the code we saw in previous firebug blog example into the onComplete of a Save button. In this way when a document is updated within the application. A notification is sent out to all the people looking at the page, updating the data for them.

 

<xp:button value="Save" id="button1" rendered="#{javascript:document1.isEditable()}">
	<xp:eventHandler event="onclick" submit="true" refreshMode="partial"
		save="true" refreshId="blank">
		<xp:this.onComplete>
		<![CDATA[
			var socketServerURL = (location.href.indexOf('copper.xomino.com')>0) ? "http://copper.xomino.com:3000" : 'http://xominosocket.mybluemix.net'

			var data = {
			  refreshId: 'wrapper',
			  nickname: 'automated'
			   };

			  console.log(data)
			  $.ajax({ url:
			          socketServerURL+"/xpagesRefresh",
			      type: "POST",
			      data: data
			  }).done(function( msg ) {
			      console.log( msg);
			  });
			]]>
			</xp:this.onComplete>
	</xp:eventHandler>
	</xp:button>

Demonstration

The video below shows how we are able to trigger a partial refresh after updating a document within the application. Note the screen flickers grey as the CSS change happens before the partial refresh. It is so quick it is almost instant.

Pushing to Bluemix

As before, pushing my new code to Bluemix is as simple as checking it in to the jazz hub repository and redeploying. In the picture below we can see that we are using marky.psclistens.com as the application domain and not copper.xomino.com. As we showed before, if not copper then use Bluemix.

b6

 

We create the capability locally, tested it, proved it and deployed it seamlessly to Bluemix with a “Commit and Push” – and that is *so* cool 🙂

Conclusion
In this article we saw how to trigger core XPages functionality automatically without the user having to interact with the application. In the next article we will look at how to improve on this, frankly horrible, user experience.

Thanks Dave 🙂