Wednesday, April 16, 2014

Abstract Submission Now Open for MWLUG 2014 !!!

I am happy to announce that abstract submission is now open for the MWLUG 2014 Conference.  It will close on May 16, 2014 at 5:00 PM.  We have a limited number of speaking slots.

The host city for our 6th MWLUG conference is Grand Rapids, Michigan at the Amway Grand Plaza Hotel from August 27 through August 29, 2014.



Have knowledge that you would like to share with others?  Always wanted to speak on a topic but have not been given the opportunity?  Here is an opportunity for your to share your knowledge and speak at a major LUG conference.  Likely always, we reserve a portion of the speaking slots to new speakers.  So do not be shy and join us and share your knowledge!  Presentation sessions are 1 hour long with 15 minute breaks between sessions. Workshops are up to 2 hours long.  Workshops occur on Wednesday August 27, 2014.

The session tracks for MWLUG 2014 are:
  • Application Development
  • Best Practices and Customer Business Cases
  • Mobility and Web Security
  • Open Source with ICS
  • System Administration

Open Source with ICS is a new topic that we have for MWLUG 2014.  We have remove Social Business from this year's list because that is what we all do as part of the ICS community so it was redundant.

To learn more about MWLUG 2014 and submit your abstract go to: http://mwlug.com

Registration for MWLUG 2014 will begin on May 1, 2014.


Tuesday, April 1, 2014

MWLUG 2014 - What we bring and what we are

Each year we create a new theme for MWLUG and is always a challenge. But this year it was easy.  I took a hard look of what is a LUG and what do we do.  It is not just about the collaboration technology that we are so fond of, it is all about us.  We get together to learn from each other, build relationships and friendships, and give back to our community.  We connect with each other, regardless of whether we are IBM customers, IBM Business Partners, or IBMers. So the theme for MWLUG 2014 is:

"Connecting the Human Community"

The MWLUG 2014 web site is now up and running. http://mwlug.com

If you are interested in sponsorship please contact me.  Unfortunately, the main room that was assigned to MWLUG had the wrong square footage and I have been working with the hotel to figure out a new layout and location within the hotel. Still waiting for a response from the hotel in the new layout for the exhibitor showcase. I will be sending out the sponsorship package soon.

Monday, March 31, 2014

Don't Get Disconnected with Connect

Here is another of my "My Experience in Building Dojo Widgets" post.

Dojo.connect (dojo/on) is a versatile and important part of dojo that handle events.  Along with dojo.subscribe and dojo.publish these three features of Dojo provide a powerful set of tools to query the DOM.


<div class="widget" id="happy">
<ul>
<li id="1">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="2">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="3">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="4">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="5">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
</ul>
</div>


Referencing my widget that I used in my last blog, I can connect this list widget using the following lines of code and create event responses accordingly.


dojo.query('ul > li',this.domNode).connect('onclick',function(e){
  alert(e.target.tagName);
});


If this list widget does not change throughout the existence of this page, this code is perfectly fine.

Let say that during the use of this web page the list needs to be updated.  If you clear the list using for example dojo.destroy or dojo.empty and repopulate the page, you can reapply dojo.connect and it will work.  However, the connections to the previous DOM nodes that you have destroyed still exist in Dojo.  Normally, this is fine though you use up more and more memory. 

However, in a more complex widget where the behavior of list DOM Nodes is different, this will come and bite you.  For example, below is a grid that has a toolbar with buttons and dropdown buttons that is dynamic.



In this widget, the toolbar will change depending on what tab you select in a tab widget that is on the same page.  If you open the button menu and click outside of the menu we want the menu to close.  However when you destroy the first toolbar and create the second, the dojo event handler still thinks that the first toolbar is there.  So the connection for closing the menu is still there and if you click anywhere on the body of the page, you will create a nasty JavaScript error.  

In order t remedy the situation, dojo provide dojo.disconnect.  Dojo.disconnect removes any event connection created by dojo.connect.  In order to disconnect an event you need to get a handle to the connection.  So from our previous example, we can assign a handle to the connections.

var handle=dojo.query('ul > li',this.domNode).connect('onclick',function(e){
  alert(e.target.tagName);
});
Since we are creating a list of connections "handle" is an array of connections. So when you what to refresh the list, we need to first get an array of handles so that we can disconnect them before rebuilding the widget DOM. So we first need to declare an array to store the list of handles.  I normally declare this in the widget constructor:

constructor:function(){
    this.connections=[];
});

So before you refresh the list widget and add new DOM nodes disconnect any existing connections that the widget has then destroy the DOM nodes, rebuild the DOM nodes, and store the new connection handles into the disconnect array, this.connections.  Therefore, the code for creating event connections becomes.

dojo.forEach(this.connections,function(connection){
      dojo.disconnect(connection);
});
var listNode=dojo.query('ul',this.domNode)[0];
dojo.empty(listNode);
var handle=dojo.query('ul > li',this.domNode).connect('onclick',function(e){
      alert(e.target.tagName);
});
this.connections.push.apply(this.connections,handle);

Hope this was useful.






Tuesday, March 25, 2014

When This is This and What is This, but What is not This, Dojo Event and Objects

In the past couple of years, I have been building Dojo Bootstrap widgets from stratch rather than using standard Dojo widgets and styling using a Bootstrap theme.  Why in the world would you do that might you ask.  Sometimes I also ask myself that question. There are many advantages, including adding security features that are not founded normally. Since we RESTFul JSON services, the widgets are optimized for our format.  In addition, the widgets are automatically binded with the RESTFul JSON services when the web page is instantiated. 

So as part of my Dojo adventures, I had to learn and relearn Dojo again and again. There is so many different ways to do things, but the right way is sometimes elusive.  One advantage of Dojo over JQuery is that Dojo forces you to use a pattern for creating widgets which I really like.  It is hard enough for me to follow what I did 2 months ago.  Imagine if another developer had to follow my code years later.

One problem is that like all software development, there are lot of stuff that are not written down in the documentation and they just assumed that you know it.  So here is a few important things that I learned that is extreme helpful.

If you use Bootstrap widgets, the HTML below is very familar to you.

<div class="widget" id="happy">
<ul>
<li id="1">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="2">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="3">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="4">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
<li id="5">
  <a href="#" tabindex="-1"><i class="icon-tools"></i>Hello</a>
 </li>
</ul>
</div>
To connect this widget to an event you can use this simple few lines of code where "e" is the event handler.

dojo.query('ul > li',this.domNode).connect('onclick',function(e){
  alert(e.target.tagName);
});


or for even shorter number of characters:

dojo.query('ul > li',this.domNode).onclick(function(e){
  alert(e.target.tagName);
});

So when you click on the widget, an alert box will appear with the tagname of the element. But what if you want to display the id of the widget. You could get it by using:

dojo.query('ul > li',this.domNode).connect('onclick',function(e){
  alert(e.target.parentNode.parentNode.parentNode.id );
});

as long as you click on the A tag. However, if you click on the "I" tag then you would need to use

dojo.query('ul > li',this.domNode).connect('onclick',function(e){
 alert(e.target.parentNode.parentNode.parentNode.parentNode.id );
});


An easier way is to pass the reference of the widget itself which is defined in Dojo as "this".  This can be accomplished by passing it as an argument:

dojo.query('ul > li',this.domNode).connect('onclick',this,function(e){
 alert(this.id);
});


So "this" is "this". Much easier isn't it. You can also redefine "this" as "what" and accomplish the same thing.

var what=this;
dojo.query('ul > li',this.domNode).connect('onclick',function(e){
 alert(what.id);
});

So what if you need to determine the id of the "LI" tag that you have clicked on, which is typical of a widget like a listbox, combobox, or menu? Again you can use the following if you clicked on the "A" tag:

dojo.query('ul > li',this.domNode).connect('onclick',function(e){
 alert(e.target.parentNode.id );
});

or if you click on the "I" tag:

dojo.query('ul > li',this.domNode).connect('onclick',function(e){
 alert(e.target.parentNode.parentNode.id );
});

This can get messly and this was what I was doing until I figured it out through experimentation. You can not find this in Dojo documentation. In this scenario, if you need to get the id of the LI tag, the reference of the "LI" tag is "this" since we are using dojo.query('ul > li') to define an event array.
 
dojo.query('ul > li',this.domNode).connect('onclick',function(e){
 alert(this.id);  // equal "3" when you click on the LI tag with id="3"
});

So no matter if you are clicking on the "A" tag or "I" tag you have the reference of the "LI" tag.
Now, if you also need to reference the widget itself you do not want to pass the reference of the widget as an argument as we did before.  That is because your will override the reference of LI with the reference of the widget.  So in order to reference the widget you need to define "this" as "what"

var what=this;
dojo.query('ul > li',this.domNode).connect('onclick',function(e){
 alert(this.id);  // "3"
 alert(what.id);  //"happy"

});


So now "what" is not "this". I hope "this" was helpful to you.  Coming soon I will let you know "what" you can do to tie events to dialog box event responses. 

Thursday, February 20, 2014

Making Technical Support Easy with Correct Browser Detection including IE11

In an ideal web application world, all your users are using the same version of the same web browser.  Unfortunately, this is not the case even in the corporate environment.  One of the most painful things to do is trying to diagnose browser specific issues and trying to determine the version of the browser that the user has.  Even if you tell your client that it is only guaranteed to work on a certain version, you still get someone using a different version.  So instead of constantly contacting the user or the IT department to determine their version, we decided to integrate browser detection logging into our iPhora logging process which tracks all user access and activities.  Therefore, when a user complains that they have an issue, we could easily look at the log and determine what browser and what version that they are using.  We incorporate that into the RESTful API to get an accurate return of browser info.

However, IE 11 as many knows does not return the correct information using dojo.isIE.  So I found in stackoverflow.com a function which I tested and works.  Now we can easily determine the browser correctly and diagnose the problem. Of course this will break in IE12.

function getInternetExplorerVersion()
{
  var rv = -1;
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  else if (navigator.appName == 'Netscape')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}

Tuesday, February 11, 2014

Domino <===> Scott Adams

Again this year, I did not attend IBMConnect. Last year it was for personal reasons, this year it did not make sense given the direction that I see IBMConnect heading towards.  However, I really appreciated that IBM had a number of sessions live and recorded on Livestream for me to watch.  What I really miss is not the sessions, but seeing the people within our community. But that is OK since I will most likely see them at ICON and MWLUG. And I always have Twitter.  The most compelling session for me was the OGS with Scott Adams.  To me what Scott Adams said about himself was a reflection of what I feel about Domino/XWork.  As he mentioned in his presentation, he is not the best in anything he does, like drawing. He practices and tries and eventually become better at it.  That is how I feel about Domino/XWork.

We have been looking into other server technologies and see what we are missing.  Should we venture off into another server platform? Domino is not fastest compared to other technologies, it is not cool compare to nodejs, its HTTP thread is small compared to other technologies, its NoSQL technologies is limited by the 64GBytes file size and 32K limits, view indexing should be redesigned, each time I talk to someone they make fun of me for working with old technology, with the exception of the Windows version the SSL technology is old and so on and on. 

But as Scott Adams said, I am OK with that, because just like Scott Adams, Domino/XWork is flexible. We can and do build on top of what we have and that is the key!
  • SSL not up-to-date, proxy it with Nginx server
  • Need bigger database infrastructure, create connectors to CouchDb or MongoDB
  • Need more threads, get a bigger server, it will still be smaller than a Websphere-based server
  • Need bigger field sizes, use MIME
  • and so on
Because of its flexibility, we as a community will figure out a method to address any limitations.

But one thing that cannot be beaten if IMPLEMENTED CORRECTLY is SECURITY.  So when others are making fun of me using Domino, I ask them how is security implemented and you know what a majority of the developer say, oh the admin handles that or why do you need that level of restrictive security. In today's world, that is the wrong answer. Again, just like NoSQL, Domino was and will be ahead of its time if that makes sense.

So as I move forward on learning, tailoring, and improving Domino/XWork for our needs, just like Scott Adams, we are improving what Domino/XWork can do and more some and when someone ask me why I am using Domino/XWork, I tell them because it is the best and meet the needs of all my current AND future customers.


Friday, January 24, 2014

Why attend LinuxFest at IBM Connect 2014

Thanks to Bill Malchisky, LinuxFest V is back at IBM Connect 2014. It will be held on Thursday, January 30, 2014 at 12:30 PM to 1:30 PM at the Dolphin - Oceanic 2.  Though it is not an official session, this is one of the sessions that I have always attended at Lotusphere/IBM Connect in the past. There is no marketing BS, all technical knowledge from some of the best Linux experts in the IBM Community.  And they tell you like it is.

As a software architect, designer, and developer, it is very important that you understand the operating system that your application is running on from the perspective of resources and security. This determines how you approach the design and architecture of your application.  Linux has become a significant part of the IBM Collaboration environment and its importance has been growing especially if you are looking at cloud-based solutions.  As a company, almost all our servers are on Linux and with a few desktops.  Even if you are running a Windows shop, you should attend this session.

So if you are an administrator or developer and attending IBM Connect 2014 you should attend this unofficial session at IBM Connect. Special thanks to Red Hat for sponsoring. For more information about this session go to Bill's blog:

http://www.billmal.com/billmal/billmal.nsf/dx/linuxfestv.htm

Monday, January 20, 2014

The End of an Era

As some know we are celebrating our 23th anniversary as entrepreneurs this year.  It has been full of highs and lows.  One of most fun achievement that we had was in the first couple of years as ReCor.  Now it is most standard corporate training with ReCor and social collaboration and BPM technology with Phora Group and our iPhora solutions.

As one starts out, you try to determine your bearings.  Usually reality hits and you throw out all the business plans and marketing stuff.  So early on we did some stuff for free hoping that something might come out of it in the future.  And that is what happened.  About a year later, the person we helped out came back to us to develop a kiosk for an exhibit.  We did not know much about kiosks at that time, but we knew technology.  You have to remember that we are talking about the early 90s and there is no Internet, Windows, Macs, fancy computers.  The latest and greatest was Intel 486 processor and VGA graphics card with a whole 64 Mbytes of memory and the beginning of touch screen technology which always turned yellow after awhile.

The requirements was that it had to be a real-time interactive touch screen application that would run everyday over and over again.  Windows 3.0 came out and it sucked.  So we had to use DOS which did not have much graphics capabilities

So my two colleagues, Rob Burton and Dan Eitel tacked with me on the development of these kiosks. With no real graphics compilers out there Rob Burton was able to find a machine code based library called Fast Graphics and we built our own language compiler that ran the kiosk in real-time.

We struggle for months to get it working, but we did it!!!

These kiosks were for the Take Flight Exhibit in the Museum of Science and Industry.  Millions and millions of attendees have seen and played with these kiosks and is one of the biggest exhibits in the Museum. If you ever attended the Museum of Science and Industry, you can not miss it.  We were able to attend the opening ceremony with all the big wigs.

These kiosks have been run everyday since. During a twitter conversation with Don McNally who was attending the Museum of Science and Industry, I was told by my colleague that the museum had recently replaced our kiosks with newer one near the end of last year.  I am very saddened and proud.  We never expect the kiosks to last 19 years of continuous use.  The kiosks were turned on by powering it up and turned off by a hard power shut down.  Gateway definitely built some nice hardware those days.

So to this day, these kiosk applications are the longest running applications that we ever built and we are proud of what we done and achieved. It was a fun project that resulted in where we are as entrepreneurs.