Thursday, March 12, 2015

Creating a Reference Letter Writing App with LiveCode: New and Improved Design

Yes, I just couldn't help myself. After creating the initial prototype of a reference letter writing app "just for fun," and then realizing there was a much better design strategy just as I was finishing it, I just had to follow through on building the new design. Recall from my previous posting that it occurred to me - late - that a much better approach would be to use "piped" or replaceable text to build a letter template within a simple text field. This allows the user to simply paste in a letter template, or write a new template from scratch. Categories can then be embedded with the use of open and close braces, such as {myRating}. (The survey tool Qualtrics calls this feature "piped" text, hence the origin of my use of the term, but I think "replaceable text" is clearer, so I'll use that term from here on out.)

The resulting app works very well. I even added the feature where the app automatically saves the most recent letter template, addressee information, candidate information, and all the categories created up to that point.

I have also changed the name of the app to "Report and Letter Writing App" to reflect the extended range of uses I think the app could be used for. For example, I see myself using it to quickly generate student feedback on low stakes assignments. But, I can easily see uses in fields other than education, such as a doctor who needs to write a short patient report.

Here's a video demonstration of the app:


How the App Works


Using the app involves a four-step process. In step 1, the user is given a blank text field within which to write a letter template. At any point, the user can create a category for replaceable text. Adding the category to the letter template is done simply by double-clicking on the category name. The category can be updated as often as one wishes with as many choices for the replaceable text added as desired.

In step 2, the user enters basic information for the candidate - name and gender - and the name and address to whom the letter is addressed.

In step 3, the user simply makes the choices from all of the replaceable text categories that are appropriate for that particular candidate.

In the final step, the letter is generated and the user simply copies the resulting letter to the clipboard for pasting into a word processor or online form.

This app version still has many limitations - hey, I created it very quickly after all! For example, only the most recent letter template is saved along with all categories created to date. An obvious design feature would be to let the user save any number of letter templates with only the categories relevant to that letter.

Try It Yourself


I made a standalone version for both Macintosh and Windows - download and uzip it if you would like to try it for yourself. Be aware that both copies will make a folder titled "RLWA Program Files" in your documents folder that contain the app's management files. If you delete that folder or its contents, you will lose all of your work.


Macintosh Note: The first time you try to open it, you will likely get a message saying that it "can't be opened because it is from an unidentified developer." This is due to the Gatekeeper function that has been recently implemented in Macintosh OS X, which by default is set to only allow the opening of applications that were obtained through the Mac App store. Fortunately, it is easy to change your security settings to allow your Mac to open the app. Here are two short videos that show how to do this:
https://www.youtube.com/watch?v=gZYGzjbkmBg
https://www.youtube.com/watch?v=rmk6kiB4sw4 (this explanation is better, but the audio quality is poor)


Windows Note: This is an untested version, but it seemed to work just fine using Windows 7.

Programming Challenges


There were all sorts of interesting challenges to building this app and I learned many new LiveCode skills as a result. Below are two examples.

Identifying the Location of the Category Insertion Point


One challenge was learning how to note the location of the focus within a text field. I used the following script and attached it to the field "letter" on the card where one builds the letter template to accomplish this:

global varInsertion

on mouseleave
   put the selectedChunk of field "letter" into varInsertion
   set the itemDelimiter to space
   put item 2 of varInsertion into varInsertion
end mouseleave

What's somewhat cool about this script is that it only triggers as the mouse leaves the text field. The idea being that one could click at the point where you want to insert a category, followed by moving the mouse to the spot on the screen where the categories are listed. This movement of the mouse guarantees that the last insertion point would be noted.

Here's how it works. Consider the following sentence: "The purpose of this letter is to support the application of George Bailey."

If the word "George" is selected, the following would be put into the variable varInsertion:
char 61 to 66 of field 1

When the focus (i.e. blinking I-beam) is immediately before the "G" of George, the following is given:
char 61 to 60 of field 1

All I really want is the first number - 61 - which is the second item in the string if one uses the space character as the delimiter between items. The variable varInsertion is then used by the field containing the list of categories on the same card:

global varInsertion

on mousedoubleup
   put "{"&the selectedText of field "dynamic text"&"}" after char varInsertion-1 of field "letter"
   focus on field "letter"

end mousedoubleup

This script is only triggered when the user double-clicks on one of the available categories. The category name is then entered after the varInsertion point with braces added to each side. You might notice that I had to subtract one from varInsertion to get it to work properly.

The only small problem is that if you double-click on two categories in succession, the second always goes in front of the first, which is counter-intuitive to me. I've not been able to solve that problem, but it is a relatively minor annoyance. Otherwise, all works great.

Allowing for Cutting, Copying, and Pasting


One unexpected challenge was figuring out how to get the simplest of text functions to work within the standalone version of the app, namely cutting, copying, and pasting. These text functions worked just fine when I was building the app, but they simply didn't work in the standalone version (using the typical shortcut keys). I found this very puzzling, but luckily I came across an article in one of the LiveCode forums that addressed the issue. To resolve it, I simply had to add the following code to the stack script:

on copyKey
   copy the selection
end copyKey

on cutKey
   copy the selection
   delete the selection
end cutKey

on undoKey
   undo
end undoKey

on pasteKey
   paste
end pastekey

I've noticed this issue in other projects I've built, so it's good to finally get to the root of the problem and solve it.

Final Thoughts


Yes, what started out as a fun project just to prove I could do it to some of my colleagues has turned out to be a very nifty little app. Similar to the first version, I created this second version in about a week working on it here and there. So, not much time was needed, thanks to the wonderful programming environment of LiveCode and especially LiveCode's excellent text processing features. I learned some great new LiveCode commands and developed a few new programming skills along the way that will come in very handy I'm sure for future projects. I definitely see myself coming back and working on the app to develop it into a full-fledged app worthy of sharing.

1 comment:

  1. Hello Lloyd,

    I liked the app. It's very similar to what I'm trying to embbed into an app i'm developing with LiveCode. The video itself is enough to give me an Idea of how to develop this letter template making app. How long did it take for you to program it? by any chance can you share the source code? Maybe I could save up some time coding. thank you!

    Regards,
    Juan.

    ReplyDelete