Wednesday, November 25, 2015

Testing custom elements

I know I promised my config file, but that will have to wait for this post...

I have a lot of custom elements in my app. Writing unit tests for them is one of the most important ways that I can have confidence that the app actually works. But I have killed myself the last 2 days trying to get the right incantation. I looked through the Aurelia unit tests, but since I haven't actually pulled them all locally, searching is hit-and-miss and I missed. Patrick Walters (patrickwalters.net) sent me a link to the test I was looking for, and I have been able to begin writing these tests. I thought I would share the boilerplate code I use in these tests.

import {TheCustomElement} from '../../src/components/the-custom-element';
import {Container} from 'aurelia-dependency-injection';
import {TemplatingEngine} from 'aurelia-templating';
import {initialize} from 'aurelia-pal-browser';
import {DOM} from 'aurelia-pal';
// Only need this (and the register below) if you need an Element in your component
let element = document.createElement('div');

describe('The element', () => {
    let sut;
    let container;
    let templatingEngine;

    beforeEach(function() {
        initialize();
        container = new Container();
        container.registerInstance(DOM.Element, element);
        templatingEngine = container.get(TemplatingEngine);
        sut = templatingEngine.createViewModelForUnitTest(TheCustomElement);
   });
});

This code leverages the testing function createViewModelForUnitTest to actually create the element to be tested. This in turns leverages the fact that the Aurelia DI system will auto register anything you need when you create something.

All in all, it's really simple.

Once you know the magic.

Update 12/11/2015. There's a little more to the process if you have mocks that you want to use. Since createViewModelForUnitTest will use the container to get your view model's dependencies, it will not by default use your mocks. However, you can control that by giving them to the DI container to use. Since the Aurelia DI container is a "first registration wins" container, this means you will want to register your mocks before everything else (granted, in this case there aren't many other options).

For example, let's assume that I have a service.js that interacts with my backend, and I have a mock that I want to use in my tests. To use the mock, I would need to change the above to:

import {TheCustomElement} from '../../src/components/the-custom-element';
import {Container} from 'aurelia-dependency-injection';
import {TemplatingEngine} from 'aurelia-templating';
import {initialize} from 'aurelia-pal-browser';
import {DOM} from 'aurelia-pal';

class MockServiceClass {   <== This is the same name as your real service class, so the DI system can line it up
    // mock code here
}
let element = document.createElement('div');

describe('The element', () => {
    let sut;
    let container;
    let templatingEngine;

    beforeEach(function() {
        initialize();
        container = new Container();
        container.registerInstance(DOM.Element, element);
        container.registerInstance(MyServiceClass, new MockServiceClass);  <== And use the mock here
        sut = templatingEngine.createViewModelForUnitTest(TheCustomElement);
   });
});

With that, the unit test will use my mock service, while creating a "real" element for testing.

Note, there is a second method in the templating engine: createControllerForUnitTest, that creates a Controller instance. In fact, createViewModelForUnitTest uses this method to do its work, simply returning the viewModel from the controller.

Aurelia Lessons

I'm going to try and start blogging again, this time mostly around what I'm learning as I implement a new work project using Aurelia (aurelia.io). Most won't be very long, they are just meant to document what I learn and force me to think clearly about it.

For today, just my setup. I've been on this project since before Aurelia went beta. I started with the ES6 navigation skeleton, but I have ended up hand editing a lot of my configuration files. I recommend this strongly. Learning what those files do has been a big help in my growing understanding of the framework. I run on Windows 7. I'm using VS Code as my code editor. I find myself wishing it had tabs, I may have to change to a tabbed editor before I'm done. It's syntax highlighting is pretty good, though.

I'm writing using ES6, not TypeScript. No particular reason, I just started there and haven't changed. I might someday.

I'm using the gulp tasks that come with the skeleton to manage everything. Karma + jasmine for my unit tests.

I have added 5 packages to the standard download: aurelia-validation, aurelia-dialog, moment, numeral and js-cookie. All were just jspm loaded and everything's good.

Next post, I'll talk a bit about the config files and how I have structured my app.

Tuesday, April 01, 2014

Souls and Culture

This is a really old post that I never finished up. It makes reference to the following posts from 2007: Choices, Souls and the Sovereignty of God, What is a soul? Based on those posts, I wish to examine what I believe this implies about the relationship between souls and societies.

If there is anything obvious about human society, it is that we have produced a varied collection of social structures. While I believe that Western society is in many ways superior to other cultures produced throughout human history, it nonetheless remains true that men in every culture manage to find ways to live remarkably similar lives, at least in terms of the basic structures of their lives. Family, friendship, work, leisure - these are common elements of every cultural expression of man. Given this common structure, it seems plausible to me that God would, in expressing His love for the soul He created, recognize the impact on that soul that would result from placing it in a given culture. By impact, I mean both limitations and opportunities. I have heard those who strive to bring broadened opportunity to less developed cultures speak of the uncounted number of "3rd world Einsteins" who will never reach their fullest potential because they find themselves trapped in a subsistence culture where the leisure required to develop higher reasoning skills is not available.

However, if we accept that God creates souls and loves them from the moment of creation, then we have to ask whether He would in fact do such a thing. It may very well be that their are no "undiscovered Einsteins" in the 3rd world because God would not place a soul with such a potential into a 3rd world culture in the first place.

I do not want to be accused of Western bigotry. As a Westerner, I appreciate the advantages that being born and raised in the West has given me. And I can only speculate as to what opportunities are available in cultures that I am less familiar with. But no matter what the relative benefits of different cultures, it seem wholly reasonable to me to believe that God places soul into cultures of His choosing.

Another risk in this position is to assume that I believe that souls are created primarily for this life. I do not believe this. We are created for eternity with God; but I believe that He places great weight in what happens in the span of our lives, and therefore positions us in this life in whatever place  offers us the greatest chance for preparing ourselves for the next.

There is an interesting question that this raises. If God places souls into cultures based upon His recognition that the soul will best reach their potential within that culture, then cultural change is of necessity very slow. The individuals within a culture are those best-suited for that culture; any individual who would likely push for large change will most likely find themselves in a culture more to their personality. This makes the struggle of the prophet more compelling, they are most likely "souls out-of-place,"except for the fact that they are exactly where God has placed them.

Monday, March 31, 2014

Blogging - again

If you've known me for very long, you know that blogging is an on again/off again proposition. I'm on again, and hope to be so for a while. I thought I would take a second to explain why. Late last week on the the men who works for me, Terry Plyler, sent me an article. This is one of the things that Terry does for me; several of the most significant technology articles I have read over the last couple of years have originate from Terry. This one is titled How to Scale Yourself and Get More Done Than You Thought Possible. It is a summary of a talk given by Scott Hanselman, one of Microsoft's project managers, and it is must reading for anyone who is breathing. I'm not going to bore you with a summary of the article; what I want to do is give you my 4 takeaways.


  1. Inbox Issues. Scott recommends that you have a very precise organization for your inbox and that you use tools to manage it. I receive at least 200 emails every day, and my inbox is my to do list. My problem is that I let the arrival of emails drive my life. I am not sure how I'm going to do it, but I am going to change that. Somehow, I am going to take back the reins of my email.
  2. Reserve Fridays for Reflection. The idea here is to become aware of goals and outcomes - 3 each, for a day, a week and a year. I am not naturally inclined in that direction, but I could stand to become more so. Again, I'm not sure exactly what that will look like, but it's going to change for me.
  3. Try the Pomodoro Technique. 25 minute sprints in which nothing is allowed to distract you. I "multitask," which works for me because my cost of task switching (read the article) is pretty small. But I rarely give myself 25 minutes of uninterrupted time. That is going to change. I will close my email and put up some indicator so that everyone knows I'm focused; and then focus.
  4. Conserve Your Keystrokes. For Scott (and for me), this means blogging. If I want to share something technical, spiritual, philosophical or personal, blogging it increases the likelihood that it will outlive me. Further, writing helps me tie things up nicely; if I just say it, it is never as locked-in as if I write it.
So, I have begun blogging again. At least one post a day, usually at the end of the day, to reflect on something I have learned.

Sunday, March 30, 2014

Noah - A Review

I went and watched the movie Noah with my wife Bethany and younger son Michael yesterday. I had heard a number of different things about the movie, including a couple of interviews with the writer and director Darren Aronofsky. I knew the people of faith were divided in their expectations of the movie; but I went in with an open mind. Like most of us, I want to see movies that treat my faith with respect, and I want them to do well. Did I find that at the theater this time? Note: there will not be any spoilers in this blog. I will keep the discussion in general terms. If you wish to see the movie, you can continue reading without fear of me giving anything away. The short answer to the first part is, "Yes." I know this is going to produce some controversy. Now, I am not saying that I think the events of Noah's life looked anything like the movie depicts. In order to take a short story that occupies a mere 3 chapters in Genesis and turn it into a feature length movie, the movie's makers had to take great liberties with the story, and augment it with their own imaginations. I don't even agree with many of the choices they made - I would much rather have seen some things done differently. But those are creative differences. What matters to me the most is that the makers of the film did not choose to mock the story in any way. The entire tale is couched in concepts that are entirely consistent with the meaning and purpose of the Biblical story. Ideas such as fallen angels, miracles, evil, and sin are woven into the story without any sense of sarcasm. The depths of man's depravity are presented as a given and worthy of judgement. Noah's struggle with hearing from God and doing His will are struggles that every person of faith can identify with, even if his struggles are at a level that we will never experience. Several complaints have been leveled against the film by believers, and I want to address them briefly. First, it is said that God is never mentioned by name in the entire movie. I believe this charge to be unfair. True, the word "God" is never used in the movie; the filmmakers prefer the identifier "The Creator" when speaking of Him. But this is merely a semantic difference. Everyone who watched the movie knows exactly who they are speaking of, and there is nothing about The Creator that is in any way inconsistent with the nature and character of the God of the Bible. Just as the name of God never appears in the book of Esther, but there is no doubt who had it working behind the scenes, so it is with this movie. The Creator is the God of the Bible. Second, I have heard some complain that it has an underlying environmentalist message. The only possible source of this complaint is with Noah's struggle to understand if God intends for there to be men on the earth after the flood. But my reading of the opening verses of Genesis 6 gives me very much the impression that if it weren't for Noah, God would not have had any humans on the earth after the flood. The evil in men's hearts was too pervasive. Sure, it is possible to read an anti-human environmentalist message into Noah's struggles, but only if you read them into Genesis 6 as well. Finally, I can imagine some believers disturbed by the imagery of the creation story, which clearly (to me) represents an evolutionary perspective. Now, if you know me, you know that that isn't going to disturb me. But before you get too upset that the presentation doesn't take 6 literal days, let me ask you - does not the presentation clearly indicate that the creation process was the ongoing handiwork of The Creator? And think of the audience. Had the film makers opted for a 6 day narrative, they would have lost the ability to speak to the large audience that cannot accept such a time frame. We as believers are more forgiving, having been taught by our Lord to look at deeper things, and can look past the superficial time frame to rejoice at a telling of the beginning that acknowledges the greatness of the creative work. Rather than being disturbed by a secondary issue, we can worship the Creator while sitting in a movie theater eating popcorn. But what about the movie itself? Did I enjoy it? My honest answer is very mixed. I think the film making was spectacular. The acting was very good. Michael complained that it was "too fantasy" for a story that wasn't fantasy. Perhaps he is right. But the real reason I struggled to enjoy the movie is that it was too real. The story is not a child's Sunday School story, with animals walking calmly into a floating zoo so that God could save them "2 by 2". It is an adult's story, telling of the very real pain and conflict present in the Biblical story. Noah was a righteous man surrounded by horrific evil. He was asked by God to perform a super-human task, and to watch as everything he had ever known was destroyed. In the flood scene we hear the screams of people dying just outside the boat - do we think this wasn't the experience of Noah and his family? Remember, in the Biblical story, God Himself shut the door of the ark, presumably so that Noah and his family would be powerless to save even one other person. This is not a sweet story told at bedtime to help a child go to sleep; this is a story of tragedy and destruction, one that would give us nightmares if we ourselves had lived through it. Understanding the psychological trauma experienced by Noah and his family, it is no wonder that the first time we encounter Noah off of the ark he is drunk - the trauma may very well have haunted his sleep for the next 350 years. How is it possible to enjoy such a story? It isn't. But I believe that people of faith should see the movie for two reasons. The first is a very practical one. If we want Hollywood to choose to make movies that take our faith seriously, these movies must succeed when they are made. But the other in a reason of faith. The movie raises questions of belief and action, questions of justice and faith, questions of good and evil. Do you believe in a God who creates and destroys? Do you believe that men, while made in His image, are corrupt through and through? This movie will force you to confront that belief, and it will, if you allow it, let you leave with your faith not only intact, but strengthened as you see God triumph through the actions of imperfect, broken men and women. Men and women like you and I.

Tuesday, July 19, 2011

Styling optgroups

An earlier post noted that I had managed to go a long time without learning about the optgroup feature that allows items in a drop down list to be grouped under sub-headings. Yesterday, I wanted to change the default look, so I did a quick google search to see if anyone had any nice styling examples that I could adapt - this is my normal design policy as I am a poor original designer.

Basically, there were none (this makes me feel better - apparently I am not the only web developer who has overlooked this feature). So I set out to develop my own. My first style rule was a simple selector on optgroup:

optgroup {
    background-color: #023373;
    color: #ffffff;
}

I was hoping just the group title would be in dark blue with white text, but instead the entire group was—which meant that then entire list was so colored. So I added a second rule:
optgroup option {
    background-color: white;
    color: black;
}
This got it. Now my headers were blue bars with white text, but the rest of the list was back to normal. All that remained was to give the group titles a bit better look: I wanted them centered with a little spacing. My final rules:

optgroup {
    background-color: #023373;
    color: #ffffff;
    font-weight: bold;
    font-style: normal;
    padding: 3px 0 0 0;
    text-align: center;
}
        
optgroup option {
    background-color: #ffffff;
    color: #000000;
    padding: 0 0 0 1em;
    text-align: left;
}

Note that I had to reset the styling for the option. I initially had left off the padding rule for the option elements, and the actual list items were flush left.

Here's an example of the final look:



Friday, July 15, 2011

Design by accident

Wow! 3 in one day...

I am a poor original designer. That is, if you give me a blank page, my designs will be at best passable. I'm not too bad at improving a design, so I can be a useful member of a design team, as long as someone else has the original ideas.

One consequence of this is that my best designs are accidental. Case in point: today, I decided that I did not like the graphical buttons that I was using throughout mypeoplematter. I went to the css button generator site to try out a button using the overall color scheme for the site. I ended up with something that I liked, so I updated my style sheets and voila! New buttons. I liked them a lot better, but because I had used a very small padding value in the style sheets, some were exceptionally small. So, I added a min-width attribute to the style. This was the design accident.

When I went to look at the buttons, they were left-justified. And I loved it! I have not seen left-justified buttons on a web site before, so I had no idea how cool they could look.

Example

An example above. I have to admit, I like this significantly better than centered buttons. I wonder, has anyone else an opinion?

UpdatePanel animations and focus

My site at mypeoplematter makes extensive use of UpdatePanels to provide a more pleasant user experience. For pages that submit data to the database (and might therefore take some time to return), I use UpdatePanelAnimationExtenders to give a visual indication that something is happening. So far, so good. My pages don't flash, and the user knows when they have to wait.

I have a page for entering weekly donations. Most churches do this in a large batch, so the page is designed to be very easy to use: the tab order is very predictable, you can press the Enter key when you have entered all the necessary information, etc. Unfortunately, when I add an UpdatePanel and the AnimationExtender to this page, I lost a critical usability feature: the page did not set the focus to the proper control.

This is one of those problems that is well documented on the web, but not well solved. I found my answer here, in the midst of a lot of incorrect suggestions. Whet I have done is added an AnimationExtender to the TextBox that I want to have control. That AnimationExtender uses the OnLoad animation to set the focus. It's a little kludgy, it would be nice if the UpdatePanelAnimationExtender did it correctly in the first place.

But what's really nice is that I was able to hide the code in a custom control I had already written. The UpdatePanelAnimationExtender is complex to specify, and requires some javascript to make it all work. I had already encapsulated all of that into a composite control that I could just drop onto my page thus:

<mypeople:UpdateAnimation ID="updateAnimation" runat="server" AnimationTargetID="wholePage" UpdatePanelID="upnlContent" FocusControlID="donorLookup" />

I added the FocusControlID attribute, and added some code to generate the necessary controls and javascript:

protected override void CreateChildControls() {
 ... other code for the update panel

 // If there is a FocusControlID, add an extender to set the focus
 focusAE = null;
 if (!String.IsNullOrEmpty(FocusControlID)) {
  UpdatePanel upnl = Page.MuchBetterFindControl(UpdatePanelID);
  focusAE = new AjaxControlToolkit.AnimationExtender {
   TargetControlID = FocusControlID, 
   Animations = "",
  };
  upnl.Controls[0].Controls.Add(focusAE);
 } // if

 ... code to build the page
} // CreateChildControls

protected override void OnPreRender(EventArgs e) {
 if (!String.IsNullOrEmpty(FocusControlID)) {
  Control theControl = NamingContainer.FindControl(FocusControlID);
  String controlID = FocusControlID;
  if (theControl != null) {
   if (theControl is PartyLookup) {
    controlID = ((PartyLookup)theControl).TextBoxClientID;
   } else {
    controlID = theControl.ClientID;
   } // if
  } // if
  js += "\nfunction OnLoad_FocusField() { UpdateExtenderFocusField('" + 
        controlID + "'); }";
 } // if
} // OnPreRender

The method MuchBetterFindControl is from here. It searches the hierarchy of control for the control with the indicated ID.

An interesting note: I cannot create the UpdatePanelAnimationExtender inside the UpdatePanel, but I have to create the focus control's AnimationExtender inside the UpdatePanel. So, in the code for CreateChildControls, I make sure to add the extender to the UpdatePanel's controls, not to those of the composite control.

All in all, this turned out to be a nifty, relatively clean solution to a problem that remains unsolved in most of the places I saw it on the Internet. If you would like the code, email me and I will bundle up the pieces for you.

Worship word: presents

Theologians (and I'm sure some who might read this post will be irritated) speak of the attributes of God. This is a useful way to try to understand what He has told us about Himself in the Bible, but it can sometimes get so theoretical and dry that it threatens to suck the life out of the Living God Himself.

Consider God's attribute of immutability. That this attribute is His is undeniable. 1 Samuel 15:29 and Malachi 3:6 say so explicitly. But note that these passages say that God's mind does not change, i.e., His plans and purposes for today are the same as they were yesterday and as they will be for all eternity.

What does this have to do with worship? You see, theologians get snagged on this concept. They extend it beyond this idea of immutable purpose to mean that things that happen have no impact on Him. But the Bible tells us that God takes pleasure in our worship, it tells us that He seeks worshipers. When we worship, we bring presents to the God of the universe, and He is affected by them. He created us for relationship, and our worship is an expression of that relationship. Think of it - the creator God is moved by my efforts to have relationship with Him.

I am always amazed that so wonderful a woman as Bethany chooses to love me - how much more amazing is the love of the God of Gods.

Monday, July 11, 2011

Learning

I have been writing web pages for a long time now. I started teaching HTML in 1999, and have worked for most of the last decade on projects that revolved around web pages. One would think that I probably knew most of the details of HTML - it is not a particularly complex language. Even if I didn't know all of the esoterica, surely I had all of the broad strokes, right? Well...

I was working on the accounting application within mypeoplematter. When the user needs to enter a transaction, they select an account from their chart of accounts. I am using a standard select list, which translates into a drop-down list in the web browser:



The list was too long (the basic chart of accounts has over 50 accounts in it), and there was no indication of the type of account (income / expense / bank / liability) in the list. I wanted to layout the list so that the account type was on the far-right, with the account name left-justified, but this is not supported by the HTML spec, so I was looking around the web for other ideas.

I found someone's code that had provided something like this, and was looking through it to try and understand what they did. In the midst of the code, there was something about optgroups. I didn't know what that was, so I googled it. Turns out, you can group items in select lists using optgroup. Over a decade of experience, and here was something new. Not only that, but it solves my problem perfectly. By the way, for programmers who find this, I will post at the end a small class that extends the standard .NET DropDownList to support retrieving the optgroup from the data source.




But my real point here is not about optgroups. My point is about knowledge. It seemed entirely reasonable to me to assume that I knew most of the features of HTML 4 - it is, after all, pretty simple. But here was something I had simply never encountered. It was a humbling moment. And of course, it made me realize that this experience is probably much more common than I realize. It is probably so for all of us. I know this is true: it just pays to be reminded:
It is not the things we know that give us the most trouble; it's not even the things we know we don't know; it's the things we don't know we don't know that are the biggest issue.
Humility doesn't always come easy for me. It's helpful to be reminded.

Programmers - here, in its entirety, is my DropDownList extension - it doesn't format well on my blog site, but if you select it and paste it into a text editor, it's all there:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MyPeople.Extensions;

/// 

/// This class extends the built-in DropDownList to provide support for retriving the name of an optgroup from the database.
/// 
namespace MyPeople.WebControls {
    public class OptGroupDropDownList : DropDownList {
        public OptGroupDropDownList() { }

        /// 
        /// The field in the datasource that provides the value for the optgroup. IF not set, then the list behaves as the built-in dropdownlist.
        /// 
        public string OptGroupField {
            get {
                object o = ViewState["OptGroupField"];
                return (o == null) ? "" : (string)o;
            } // get
            set {
                ViewState["OptGroupField"] = value;
            } // set
        } // OptGroupField

        protected override void RenderContents(HtmlTextWriter writer) {
            if (String.IsNullOrEmpty(OptGroupField)) {
                base.RenderContents(writer);
            } else {
                bool useOptGroup = !String.IsNullOrEmpty(OptGroupField);
                String lastOptGroup = null;
                ObjectDataSource ds = Page.MuchBetterFindControl(DataSourceID);
                IEnumerable objs = ds.Select();
                foreach (object item in objs) {
                    String text = DataBinder.Eval(item, DataTextField, DataTextFormatString);
                    String val = "";
                    if (!String.IsNullOrEmpty(DataValueField)) {
                        val = DataBinder.Eval(item, DataValueField, "{0}");
                    } // if
                    bool sel = false;
                    if (!String.IsNullOrEmpty(SelectedValue)) {
                        sel = val == SelectedValue;
                    } // if

                    if (useOptGroup) {
                        string thisGroup = DataBinder.Eval(item, OptGroupField, "{0}");
                        if (thisGroup != lastOptGroup) {
                            if (lastOptGroup != null) writer.WriteLine("");
                            writer.WriteLine("", thisGroup);
                            lastOptGroup = thisGroup;
                        } // if
                    } // if
                    writer.WriteLine("", System.Web.HttpUtility.HtmlEncode(text), System.Web.HttpUtility.HtmlEncode(val), sel ? " selected='selected'" : "");
                } // foreach

                if (useOptGroup) {
                    writer.WriteLine("");
                } // if
            } // if
        } // RenderContents
    } // class OptGroupDropDownList
} // namespace


Monday, July 04, 2011

Naming

Happy 4th of July. It is a good thing to celebrate the birthday of the greatest nation in all of history. Not perfect, but the best we humans have done thus far.

I am working a bit today, mostly because we are going to be going away for a few days later this week and wanted to finish a particularly useful piece of code for the accounting report system. Along the way, I discovered a flaw in my design. These are always frustrating; especially when, as in this case, the design flaw touches on several aspects of the software and thus testing the fix is more time-consuming and tedious. But this design flaw was particularly frustrating, because there were signs of the problem that I overlooked. The most significant sign that I had a problem in my design was to be found in the names that I was using.

Briefly, the flaw was that I was only requiring that a single item be configured where I in fact needed two related items. As I went through my code making the change, I found that I had been confused all along, as I sometimes used one name when describing the configured item, while at other times I use another name. The two names accurately described the two items I needed, but I missed the hint until just today.

I mention this because this is one of those principles of programming that I have developed over my career: if I don't know what to name something, then I don't understand it. And if I don't understand it, I haven't fully investigated it. Normally, if I have trouble with a name, I back away from the code and attempt to clarify my understanding before I move forward. In this particular case, I let my (mistaken) belief that I knew what I needed obscure the hint that the naming issue was giving me.

I love this for another reason. The issue of naming is one of those things that touches on multiple disciplines. The centrality of naming is one of the reasons that I have confidence in the Genesis story - the God who made us understands that if we cannot name something, we don't understand it. So, one of His first tasks for man was to name the animals. It matters not to me whether you believe in the historicity of the Genesis account; it is difficult to deny the insight of the second chapter of Genesis in this matter.

This issue of naming touches in the political realm as well. One of the great powers of the media is that it often gets to name the forces within our society. The power of naming allows the namer to define the item named. It is why politicians look to name bills. The name of the bill becomes its meaning, even if they are not in fact the same thing. To name is to define and to control understanding.

Finally, I have found this principle true in my own life. Early in my adult life, I was struggling with some personal issues. I flailed away, trying to get a handle on what I was doing, until a friend gave me a name. In retrospect, the name was only partly accurate. But at the time, the name gave me something to address. In addressing the name, I found the ability to overcome the underlying issue and to move past a continuing area of struggle.

I recommend it as a life principle. If you do not understand what is happening in life, try to name it. The process of naming can often bring the understanding that has heretofore eluded you.

It also works if you write software...

Tuesday, June 28, 2011

Being left handed

I am, in case you didn't know, left-handed. I love being left-handed, the greatest men in history were predominantly left-handed (so were some of the worst). Even God is left-handed. Don't believe me? He must be, since the Bible says that Jesus is sitting on His right hand.

Anyways, there are many, many places in which being left-handed puts me at a disadvantage. Some are trivial - did you know that the printing on pens and pencils is upside-down if you hold them in your left hand? Some are minor - scissors are built so that when held in your right hand, the top blade does not obscure your view of the cut line - when held in the left hand, you must look over the blade to see your cut line. Some can be dangerous - in fact left-handers may actually live shorter lives.

Here's one I'll bet no one has noticed before. The shortcut keys for the common editing commands undo, cut, copy, and paste use the shortcuts Z, X, C, and V respectively. All of those keys are on the left side of the keyboard. So, when I am using my mouse and I want to use one of those common shortcuts, I must take my hand off of the mouse, press the desired key chord, then return to the mouse. If I have a difficult series of edits to make (this is common when I am programming) this can be very inefficient. Sometimes I even move the mouse to the right side of the keyboard for a few minutes (another advantage to being left-handed is that most of us can use out right hands fairly well for common tasks).

Probably not the biggest issue in my life, but it sure can be irritating. I can only hope that all that movement reduces the risk of repetitive motion injuries.

Model-View-Controller

I have read all about this pattern for doing UI work, but I have never seen a great need to adopt the pattern. Both Builder and Visual Studio invite you to place all of your response code directly into the UI element class, and I have gladly taken the invitation. To be honest, I had never seen a good reason to do any differently. Oh, I would wrap some concepts into external (or even internal) classes, but the basic approach has worked fine for me.

The last couple of days I have been working on the configuration assistant for the accounting system at mypeoplematter. This is an ASP Wizard control with (as of now) 11 pages, some of which feature expanding windows that allow the user to configure things like bank accounts. Very quickly the number of buttons and their callbacks became unmanageable. So I built a controller class that provided a framework for each page. Then each "page" in the wizard got its own Controller-derived class to actually handle the work. My form class was left with just a little code to abstract out navigation events, and 4 general-purpose button events that it forwards to the controllers.

The Controller class has an interface with 7 methods:
virtual public void OnEnter(secure_accounting_ConfigAssistant page);
virtual public void OnExit(secure_accounting_ConfigAssistant page);
virtual public bool SkipMe(secure_accounting_ConfigAssistant page);
virtual public void OnSelect(secure_accounting_ConfigAssistant page, object sender);
virtual public void OnShowEditor(secure_accounting_ConfigAssistant page);
virtual public void OnSaveEditor(secure_accounting_ConfigAssistant page);
virtual public void OnCancelEditor(secure_accounting_ConfigAssistant page);

It provides (empty) default implementations so that derived classes need only override the methods they need. I built a small caching mechanism to keep track of controllers throughout postbacks.

The resulting code is so clean that I will use it in every Wizard I build from here one, and probably for multi-tab pages as well. I can find the implementation of a given event handler by going to the appropriate controller and looking through at most 7 methods, rather than the over 60 that I would have needed without the controller abstraction.

Having said all that, I still do not see how MVC (or MVVC) would simplify my pages that perform a single function. Now, I have done some abstracting - most of my data entry pages have FillPage() and Gather() methods that handle the populating and retrieval from these pages. But since the pages themselves perform only a single function, I do not see the benefit to be gained from adding a controller class.

Any thoughts?

Thursday, June 23, 2011

Demonstration

--- From my "Worship Words" series ---

Last week was Vacation Bible School. One of the things I love about VBS is all the songs with lots of hand motions and dancing. The reason we do it this way is because adding the actions helps the kids to stay interested and to learn. When we make big hand motions and sing about how big or powerful God is, the motions reinforce the message.

Our word today is “demonstration.” One aspect of our role as worship leaders is that of demonstrating what we are saying to the congregation. When we raise our hands in surrender, when we clap with joy, when we dance (or bounce) to a song of celebration, our actions reinforce the message we are singing. The principle we use when teaching children applies to adults as well – many people in our congregation are learning about God and how to worship Him by watching us. Let us demonstrate our words with our actions, just like we did last week at VBS.

Monday, June 20, 2011

UpdatePanels and Wizards

At the heart of my new website is a little control that does a dynamic lookup of a name as you type in a text box. Internally, I call it a PartyLookup (as the core table it searches is the Party table). Today, I am trying to add one of these controls to a rather nasty page: it has a wizard inside an update panel all in a modal popup extender. This all worked when the popup window did not have a wizard, but the page is complex enough that I decided I needed to break it up into 2 steps, hence the wizard. But my lookup control stopped working, as the dynamic javascript I generate to handle the AJAX calls was not getting emitted via the partial postback when I changed wizard steps (the lookup control is on the second page).

I searched Google for an hour, trying everything I could find. Finally, the following 2 changes worked:

For javascript I generate in the server-side code, I needed to use
ClientScript.RegisterClientScriptBlock, rather than Page.ClientScript.RegisterClientScriptBlock. This is a mysterious fix, but it works.

Second, for script that I want to include from an external source, I needed to add:
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Together, these two calls seem to have gotten my control working in this new environment. We will see...

Saturday, June 18, 2011

Tax increases and subsidies

As anyone who knows me can attest. I am a fiscal conservative politically. My first presidential vote was for Ronald Reagan, and I considered it the best gift a young voter could have been given. I am against tax increases, period.

But I don't understand Grover Nordquist's position on the ethanol subsidies and other similar issues. I want the government to simplify the tax code, and I want the government to stop picking winners and losers. Subsidies go against both. Technically, ending a subsidy has the same effect as raising taxes, but when you have such a narrowly defined subsidy, the elimination of it feels more like a reform to me.

And these are the sorts of reforms we need. Eliminate preferences for one style of business over another. Eliminate preferences for one behavior over another. Let Americans decide what they want to buy without a parental government telling them what is best for them.

Besides, the ethanol subsidy is immoral...

Friday, June 10, 2011

Worship word: approach

My wife and I head the worship team at our church. We get to be on stage occasionally, but mostly this involves us training our young team. It's a lot of fun, and I always tell my pastor that I hadn't meant to sign up for youth ministry.

One of the things I do is what I call a "worship word." Every week at practice, I take a couple of minutes and do a short teaching around a single word and its application to worship. I'm going to start posting them here every Thursday or Friday. This week's word was "approach."

-----
The Bible tells us that we are to "boldly approach the throne of grace." It is here that we meet the God who gives grace and mercy and help. As worshipers, we do this in part when we worship. Through our singing and playing, we approach the throne of the God who meets with us. I am coming to a new understanding of the remarkable nature of our relationship with this God. He is the one who dwells in inapproachable light, whom if we were to look upon him we would die; and yet we can approach him because he invites us. Just as the shed blood of Christ opens the way for us to share in his table, so it has purchased for us an invitation to approach the inapproachable God.

As a worship team, we have an additional gift. Not only do we approach God, but we are given the task of leading others as they approach him to. Our leadership in worship is intended to open the door for the congregation to follow us into the presence of the God of the Universe. What a wonderful, inexpressible opportunity!

Javascript and .NET PostBacks

I always find it interesting when I suddenly find a use for a feature of a toolkit that I never needed before. This is the story of one such event, which just happened today.

Some background: I'm working on the accounting portion of my new company's product. It is almost ready to unveil; I just have to finish a couple of data entry screens and generate the core reports. Currently, I'm working on the bank account reconciliation page.

I want it to be nicely interactive - when you check an item off, I want to immediately update the item counts and totals so that the user can see their progress toward balanced. The most effective way to do this is to use javascript, and so that is what I did.

It worked great. But I have a handful of things that require a server round-trip, or a post back. When these happened, my totals were reset. This makes sense, the server-side couldn't possibly know what all had happened since it last sent the pages. This means that I have to figure out what the user had been doing, and have my server-side code reproduce the calculations the client-side was doing (I know I could have stored the values in hidden fields, I chose not to and I'm glad, because then this story wouldn't have happened).

Where to do these calculations? The answer is to handle them in Page_Load. I've done lots of coding in Page_Load, but never in response to a post-back. My pages mostly look a lot like this:

protected void Page_Load(object sender, EventArgs e) {
    if (IsPostBack) {
    } else {
        // Lots of code here to load the page from 
        // query strings and other stuff.
    }
}

I almost never had any code in the side of the if statement when IsPostBack was true. I had about decided I never would. But here was a case where I needed to fill my page only on a post-back.

Nothing really profound, but I just think it is interesting when something new comes up for me.

Thursday, June 09, 2011

Back again

I have been trying to figure out how the blog fits in my life. Basically, it hasn't for a couple of years now.

But I love to write, and writing helps me to organize my thoughts. So I have a new plan. I'm going to try and post at least 3 times a week. The posts will be as varied as my interests - one may be something new that I discovered about programming while working; another may come from politics or religion; others may just be from everyday life. I will try to make it all interesting, and hopefully the blog will be discovered again. But even if not, this will be the place where I can look back an remember what has happened.

But this post has another, more sinister purpose (cue music) - I want to get a link back to my new company's web site in place. So, here is a shameless plug/postback to the site in an effort to get Google to notice it. You can find my company at: www.mypeoplematter.com. The company makes church management software that runs in a browser. It is designed primarily for smaller churches - it doesn't have all of the bells and whistles of the well-established packages. But it is my experience that most churches don't want all of those things. They just need a few features: contact management, donation tracking, directories and communications, and accounting. When I finish the accounting piece in the next few weeks, I will have all of these features. And my pricing is designed for smaller churches, just a minimal monthly subscription fee, tiered based on church size. A church of under 120 will pay just $25/month for the entire package, only $15/month if they don't need accounting.

Anyways, that's what's up. If you're still out there, it's nice to be speaking again.

Thursday, April 16, 2009

Religion and the brain

Michael Gerson reviews research on the interaction of religion and the brain here.

This study is the most balanced I have yet seen. The author of the study is himself a skeptic, but admits that his research does not disprove the reality of religious experience. Neither does it prove it. How you interpret the findings will undoubtedly be influenced greatly by whether or not you are already religious.

I am just always happy when a skeptical scientist if honest enough to admit that science isn't the end-all of truth. I'll admit it about religious truth, glad to have a reciprocation.