Xomino

Domino with the new improved X

Going to MWLUG 2014? You need to buy these guys a beer as well….

Posted by mark roden on August 24, 2014

—->>>> Richard Moy <<<<—

He’s the guy you really need to thank for this event – without his dedication and enthusiasm, the most significant User Group meeting in North American this year would surely not happen.

 

Mike McGarel

helps on the web site,

Devin Olson

was the boots on the ground and help

 

Ray Bilyk

 

Be Warned though – Devin and Ray are VERY particular about their beer – Richard and Mike not so much – so ask first ;)

Posted in Just Marky, MWLUG | Leave a Comment »

Going to MWLUG 2014? Buy Dave Leedy a beer

Posted by mark roden on August 24, 2014

Yeah I know I have rattled on about this before but it holds as true today as it does any other day before.

Here is a list of reasons you should buy Dave Leedy a beer in case you were wondering…

1) really? You need a list?? Shame on you….

2) NotesIn9 has helped you – One of those videos by Dave, John, John, Brian, Chris, Graham, Jeremy, Mark, Mark, Paul, Peter, Steve, Tim, Chris, Paul, Josh, Dan, Niklas, Michael, Russ, Serdar, Sean, Mark, Brad, Frederick, Steve, Richard, Kathy, Stephan, Keith, Martin and Andrew (to name but a few) made you look better to your boss

3) Dave pays for this amazing service out of his personal pocket. By my reckoning $40 a month for 3+ years is well over $1000 dollars. A $5 beer is the LEAST you can do to repay him.

4) Dave refuses to take contributions – if it would make a difference I would do a kickstarter, but he’d refuse.

5) NotesIn9 is the largest repository of videos and tutorials, created by the largest number of different contributors in the IBM ICS community.

If he refuses to let you buy one, buy it anyway and put it in front of him. He’s going to be there for four nights so just do it.

Buy the man a beer – you owe him and it would be rude not to!!!

The line starts behind me……..join it !

Posted in Just Marky, MWLUG, NotesIn9 | 3 Comments »

Chart Directives and Dynamic Binding – MWLUG 2014 preview

Posted by mark roden on August 20, 2014

Although not directly related to the purpose of the presentation I am going to demonstrate how to use an Angular.js chart directive to bind to the application service data and create dynamic charting within the application.

m1

Changing the Zip for 1 Marky not only updates the data displayed – but also because of the data bind – auto-magically updates the chart

m2

While this in itself does not directly relate to the write once and run anywhere nature of the presentation – it does demonstrate componentized Angular.js code writing which you *might* want to write once and run anywhere……

Come and see the presentation to find out more :)

Remember to stick around until the end I am on at 3pm Friday in the main room :)

 

Posted in Angular in XPages, Angular.js, MWLUG | 6 Comments »

Accessing the original element when using Select2-focus

Posted by mark roden on August 17, 2014

In the application we are currently working on I wanted to add an ajax call to a JSON service, but only for certain fields. Rather than go through the application and add the code to every element I used a delegated focus event for the field with an attribute of  “help_fieldName”. The following HTML represents the code on the form:

          <div class="col-lg-8">
            <select help_fieldname="territory">
              <option value="UK">UK</option>
              <option value="US">US</option>
              <option value="Global">Global</option>
            </select>
          </div>
          <div class="col-lg-4">First Name</div>
          <div class="col-lg-8">
            <input type="text" class="form-control" help_fieldname="firstname" />
          </div>
          <div class="col-lg-4">Last Name</div>
          <div class="col-lg-8">
            <input type="text" class="form-control" help_fieldname="lastname" />
          </div>

The following jQuery code makes it work. The getHelp function shows/hides the help based on the boolean in the function.

$(document).ready(function(){
	$('body')
		.on('focus', '[help_fieldName]', function(){
		     getHelp(true, $(this))
		})
		.on('blur', '[help_fieldName]', function(){
		     getHelp(false, $(this))
		})
	})

 

What I found though was that when I used Select2 the field attribute was not being picked up. This is because Select2 creates it own DOM elements to display the field and the original field attributes are not transferred to this new DOM structure.

So I needed to come up with a way of accessing the original element from the select2. This turned out to be very simple – select2 emits an event on focus and blur called select2-focus and select2-blur. The event target gives me direct access to the original field the select2 is representing.

Using this simple modification to the delegation code I was able to access the help_fieldName to pass to the help Function. The image below shows the console.log, highlighting the underlying DOM element.

$(document).ready(function(){
	$('body')
		.on('focus', '[help_fieldName]', function(){
		     getHelp(true, $(this))
		})
		.on('blur', '[help_fieldName]', function(){
		     getHelp(false, $(this))
		})
		.on('select2-focus',  function(e){
		     console.log(e.target)
		     getHelp(true, $(e.target))
		})
		.on('select2-blur',  function(e){
		     getHelp(false, $(e.target))
		})
	})

s1

Posted in jQuery | 2 Comments »

Angular in XPages #8 – Directives (did someone say plugins?)

Posted by mark roden on August 10, 2014

In this article I will discuss Angular Directives and why they are near and dear to my heart

Directives

Directives in Angular are modular pieces of functionality which in some cases are very analogous to plugins in jQuery. According to the Angular documentation…

“At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.”

For more on the directive documentation look here – https://docs.angularjs.org/guide/directive

I have already shown and demonstrated some of the core Angular directives like ngApp and ngView. Those attributes within the HTML are the instructions to “Do Something Here”

<div ng-app="personApp">
    <div ng-view></div>
</div>

The on-last-repeat directive

Within my demo application I wanted to know when the table was finished loading. The problem is in Angular that there is no “I am finished with the template load” event. The reason is due to the asynchronous nature of the Angular code.

I wanted to load the table and then take an action on it. To do this I added a directive to the “repeat control” within my template for loading people.

The following example was completely plagiarized from this article – respect !

http://www.nodewiz.biz/angular-js-final-callback-after-ng-repeat/

You can see the on-last-repeat attribute within the first TR

    <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><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>

I then created a directive within my app.js to do something with the on-last-repeat

personApp.directive('onLastRepeat', function() {
    return function(scope, element, attrs) {
        if (scope.$last) setTimeout(function(){
            scope.$emit('onRepeatLast', element, attrs);
        }, 1);
    };
})

Within the code we are creating a custom “event” which can be listened for in another part of the application

  • If the last entry is triggeredhere
    then
  • $emit the onRepeatLast event within the application

Then in the PeopleListCtrl controller we set a listener -

  • $on the onRepeatLast event
  • Do something
peopleControllers.controller('PeopleListCtrl', ['$scope', '$http', 'peopleFactory',
    function ($scope, $http, peopleFactory) {
        $scope.$on('onRepeatLast', function(scope, element, attrs){
           alert('The table has loaded')
        });

a1

 

Well that is a little simple….

Yes it is but it serves to demonstrate the concept. The best part is that there are lots of people who are writing plug and play Directives for Angular – just like jQuery plugins. If I could be bothered I might even do some blog posts on useful Directives…..But is a good resource for looking at some available directives.

http://angular-js.in/

There are multiple directives for using jQuery plugins within an angular construct – this is very helpful for data binding. There are also multiple directives which are independent of jQuery and are stand along “Angular” plugins for want of a better term.

Posted in Angular in XPages, Angular.js, XPages | Tagged: , | 7 Comments »

Working on my MWLUG2014 presentation

Posted by mark roden on August 6, 2014

Just wanted to show a work in progress – screenshots of what I am working on for MWLUG2014. Part of the presentation is showing how to make your Angular applications portable.

My sample app will be the one I created as part of the Angular in XPages series.

I will walk through the code and demonstrate how I can take this stand alone application

a2

and insert it into this bootstrap demo dashboard application

a1

creating this fully functional component capability within the dashboard

angularinDashboard

 

With only 4 lines of HTML and zero XPages dependency.

Come to MWLUG2014 in Grand Rapids Michigan and find out more

PS

Make sure you plan to stick around to the end – I am not on until 3pm on Friday !!!

 

 

 

Posted in Angular in XPages, Angular.js, MWLUG, XPages | Leave a Comment »

Angular.js in XPages #7 – Writing better code using Services

Posted by mark roden on August 3, 2014

In this article I will discuss a better programming practice for Angular.js than was demonstrated in the previous articles within this series. I have mentioned before, part of the purpose this blog is very much a “learning in progress” for me. Without going through the previous articles I would not have been able to get to this point and write “better code”. Hopefully with that understanding, those of you who have been along for the ride will appreciate this and grow with me :)

Services within Angular

Within Angular there are these programmatic entities called services – and if you read around Angular programming practices (Follow @ToddMotto – http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/) you will find (as I have) that adding application logic within Controllers is generally frowned upon.

“In AngularJS world, the services are singleton objects or functions that carry out specific tasks. It holds some business logic. Separation of concern is at the heart while designing an AngularJS application. Your controller must be responsible for binding model data to views using $scope. It does not contain logic to fetch the data or manipulating it.”

http://viralpatel.net/blogs/angularjs-service-factory-tutorial/

From a maintainability perspective, as well as logical code layout perspective, having functional logic within the controller is akin to writing a 1000 line LotusScript agent  – not optimal !!

I used this article by Dan Whalin to better understand how to create a Service using a factory

So what changed?

We I changed the controller around so that code in the controller that once looked like this:

 $scope.createPerson = function(event) {
            $http({
                url: '//copper.xomino.com/xomino/ainx.nsf/api/data/documents?form=fUserName',
                data: $scope.person,
                withCredentials: true,
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                }
            })
                .success(function(data) {
                    location.href = "#/people";
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
            event.preventDefault();
            return false;
        };

now looks like this:

        $scope.createPerson = function(event) {
            dataFactory.createPerson($scope.person, event)
                .success(function(data) {
                    event.preventDefault();
                    location.href = "#/people";
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
        };

and the service looks like this:

    dataFactory.createPerson = function (person, event) {
        console.log(person)
        return $http({
            url: urlBase+'documents?form=fUserName',
            data: person,
            withCredentials: true,
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            }
        })
    };

 

Now I know you are looking at this and saying to yourself – hang on you just copied and pasted all the code and actually made it longer and more complicated – and that would be very perceptive of you – but (and I had to make this leap to believe it myself), it is better.

My example application only really has one purpose – manage people. In a more complex application a separation of logic into like components would make sense. By using the service I have separated all my “do stuff with people” out into a people Service. When I built the next part of the application – to do with buildings for example I would create a buildings Service and manage all my building logic there.

Let the controller do it’s job and bind the data to the View and keep your logic out of the controller and into Services.

The final Code

My service (service.js)

personApp.factory('dataFactory', ['$http', '$timeout', function($http, $timeout) {

    var urlBase = '//copper.xomino.com/xomino/ainx.nsf/api/data/';
    var dataFactory = {};

    dataFactory.getPeople = function () {
        return  $http.get(urlBase+'collections/name/byFirstName5Col?open&count=3').success(function(data) {
            $scope.people = data;
        });

    };

    dataFactory.getPerson = function (id) {
        console.log('get person')
        return  $http.get(urlBase+'documents/unid/' + id)
    };

    dataFactory.createPerson = function (person, event) {
        console.log(person)
        return $http({
            url: urlBase+'documents?form=fUserName',
            data: person,
            withCredentials: true,
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            }
        })
    };

    dataFactory.savePerson = function (person, event, id) {
        console.log(id);
        return $http({
                url: urlBase+'documents/unid/' + id,
                data: person,
                withCredentials: true,
                method: "PATCH",
                headers: {
                    "Content-Type": "application/json"
                }
            })
    };

    dataFactory.deletePerson = function (id) {
            var temp = confirm('Are you sure you want to delete?')
            if (temp){
                return $http.delete(urlBase+'documents/unid/' + id)
            } else {
                location.href = "#/people"
            }
    };

    return dataFactory;
}]);

My controller

peopleControllers.controller('PersonDetailCtrl', ['$scope', '$routeParams', '$http', 'action', '$timeout', 'dataFactory',
    function($scope, $routeParams, $http, action, $timeout, dataFactory) {

        $scope.create = (action=='new' || action=="delete");

        if (action=="get") {
            dataFactory.getPerson($routeParams.docId)
                .success(function(data) {
                    $scope.person = data;
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
        }

        $scope.home = function(){
            location.href='#/people'
        };
        $scope.createPerson = function(event) {
            dataFactory.createPerson($scope.person, event)
                .success(function(data) {
                    event.preventDefault();
                    location.href = "#/people";
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
        };

        $scope.savePerson = function(event) {
            dataFactory.savePerson($scope.person, event, $routeParams.docId)
                .success(function(data) {
                    event.preventDefault();
                    location.href = "#/people"
                })
                .error(function(data, status, headers, config) {
                        console.log('ErrorData: ' + data);
                });
        };

        if (action=="delete") {
            dataFactory.getPerson($routeParams.docId)
                .success(function(data) {
                    $scope.person = data;
                    $timeout(function(){
                        dataFactory.deletePerson($routeParams.docId)
                            .success(function(data) {
                                $scope.person = {};
                                location.href = "#/people"
                            })
                            .error(function(data, status, headers, config) {
                                console.log('ErrorData: ' + data);
                            });
                    }, 300)
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
        };
    }]);

 

Posted in Angular in XPages, Angular.js, XPages | Tagged: , | 2 Comments »

Taking back productivity in Domino Designer (a NotesIn9 production)

Posted by mark roden on July 29, 2014

Yeah it has been a while (over 18 months) since the last time I did a NotesIn9 video but it finally happened again.

NotesIn9 149:  Database Resources and Design Definition

Doesn’t sound very exciting does it? Dave needs to work on his attention grabbing heading show names. I would have called it something more like this – but then who am I to complain – it is not my show after all ;)

NotesIn9 149:  Taking back productivity in Domino Designer 

This video revolves around some simple but not always well known facts about working with Domino Designer in Eclipse (DDE). When you use Database Resources and custom controls they slow up designer significantly. XPages developers unnecessarily put up with it and just curse out the DDE slowness. Take back your productivity and make your XPages quick again.

Using some architecting tips and the Design Definition within a custom control you can:

  • Speed up designer significantly
  • Continue to take advantage of the database resources
  • Layout your code in a more readable fashion within the DDE Design Pane
  • Take back your productivity in Domino Designer

 

Thanks as always to Dave for doing Notes In 9 – if you see Dave at MWLUG, ConnectED or any other time – buy that man a beer !!

 

Posted in NotesIn9, XPages | 1 Comment »

The consummate Champion

Posted by mark roden on July 24, 2014

As Russ Maher said today in Hey Who got the Handsome Champion it is an honor and a privilege to not only be recognized by IBM as a Champion for ICS 2014, but you also get some very cool stuff. Thanks to Amanda Bauman and Oliver Heinz for organizing “the champions” and all the gear. I just wonder what I am going to do with all of it :)

 


champion1

 

 

Seriously though, I am very humbled to be an IBM Champion !

Thank you to everyone who nominated me and made this possible :)

 

Posted in Just Marky | 12 Comments »

Web Components – Entering the ShadowDOM….

Posted by mark roden on July 9, 2014

Web Components – the future

You should first ground yourself on Web Components and read this article on Web Components and concepts, ShadowDOM, imports, templates, custom elements by Todd Motto.

Then listen to this Podcast (thanks to Steve for pointing it out) – Web Components with Peter Gasston

Once you have read/listened you will have some idea and concept about Web Components and how they are the future…..

But what I wanted to show briefly was how to enable the ShadowDOM in Chrome and what that can do for you in a cool kinda way.

HTML5 Elements

If you create a simple <input type=”number”> field on an HTML5 page you will now get a “Number Picker” which is more than just an Input field

s1

And if you look at that through the web explorer (F12) you will see the HTML Markup for that

s2

Enabling ShadowDOM

Within the Web Dev Tools for Chrome you can click on the settings button and within there under General “Show user agent shadow DOM”

s3

 

And then if we look at our Number field again you will see it is actually marked up HTML which we did not see before.

s4

 

The HTML5 number field is actually an HTML field marked up with HTML and JavaScript running within the browser. This is the fundamental concept behind Web Components – make a simple piece of HTML tag input but behind the scene do a whole load of cool things to make it functional.

 

Cool eh :)

 

Posted in Web Components | Leave a Comment »