I’m John C Bland II

Husband, Father, Tech Author, Deacon.
Founder ofย Katapult Media, and full-stack polyglot developer.
Political Free Agents Podcast Host.

I create. I launch.

YouTube Channel

I post regular fun on YouTube like me playing the bass and anything else I find fun.ย 

Get Something Built

All project work goes through Katapult Media. Business is open. Let’s chat.

Javascript: Trim sentence to N number of words

I didn’t spend time looking through any of the JS utilities to do this so if there is one publicly available I’d suggest using it since I just coded this and haven’t run it through be 2 screen refreshes. ๐Ÿ™‚

bq. function trimByWord(sentence) {
var result = sentence;
var resultArray = result.split(” “);
if(resultArray.length > 10){
resultArray = resultArray.slice(0, 10);
result = resultArray.join(” “) + “…”;
}
return result;
}

I guess we can step through the code.

#) Set _result_ to the _sentence_ value passed in so if there aren’t more than 10 words it will just return the same string.
#) Split _result_ by spaces so a sentence like “I love to blog but sometimes get to busy. I’ll try harder.” will result in an array of 12 strings.
#) If _resultArray_ has more than 10 (put whatever number you want here) words, go to the next step. If not, skip to the last step.
#) Slice the array to only grab the first 10 (again, whatever number you want here) elements (the words) in the array.
#) _join()_ the array with a space so the _resultArray_ elements are now a string and add the ellipsis to the end.
#) Return the _result_.

That’s it. There are a few upgrades I’m going to make in a few minutes. Basically make sure the last character isn’t a period (if so, ignore the “…”) and maybe a couple others.

Hope this helps.

Integrating Spry with Lightbox

“Spry”:https://labs.adobe.com/technologies/spry/home.html is a great Ajax library and is pretty easy to use but seeing as you do not have the images in the html at the time of rendering in the browser “Lightbox”:https://www.huddletogether.com/projects/lightbox2/ doesn’t have access to the current _a_ and _area_ tags in the page. So…what’s the solution?

Well, there are other ways you can make this happen but here is one:

bq. Spry.Utils.addLoadListener(function() { setTimeout(function() { myLightbox.updateImageList(); }, 1000); });

Basically add a listener so when the data is loaded simply tell _myLightbox_ to update the image list (which is the function that parses the DOM) after 1 second (1000 milliseconds), just to give Spry enough time to render the html. _myLightbox_ is the instance name Lightbox.js creates for the Lightbox instance.

Feel free to explore other ways for adding listeners/observers to Spry and post them. I didn’t find much in Google so I figured I’d post my quick fix.

AIR 1.0 and Flex 3 Released!!

That’s right. It has been a long road but we have finally made it to the end. “Mike Potter has a good post about the release”:https://weblogs.macromedia.com/flexteam/archives/2008/02/its_on_-_flex_3.cfm so I won’t go on and on but this is an AMAZING RELEASE for the Flex community and AIR is a great release for the world, IMO. We are on the brink of a new age, potentially. Let’s see where we go from here. ๐Ÿ™‚

ENJOY!

“Buy Flex 3”:https://www.adobe.com/go/flex
“Download AIR”:https://www.adobe.com/go/air

Silverlight 2.0 First Look

ScottGu published some info about Silverlight 2. In my opinion, these upgrades bring Silverlight much closer to being a serious consideration for RIA development. There have been some cool things come out but nothing quite matching anything created by other technologies. I see SL 1.0 as a “video” release. This release seems to bring the focus to application development, which is great.

“Read more about Silverlight 2.0 on ScottGu’s blog”:https://weblogs.asp.net/scottgu/archive/2008/02/22/first-look-at-silverlight-2.aspx.

Thoughts? Still afraid of it Flash Platform geeks? Is it still the devil? Is it still seen as a “ying and yang kinda thing”:https://www.youtube.com/watch?v=ESyzOpoNeMQ (funny video, “Phillip”:https://phillipkerman.com/blog/) or a competitor? ๐Ÿ™‚

My opinion…it is “getting there” but isn’t quite there. I’ll review the API/upgrades and give a full review after actually touching the code. I’m HIGHLY interested though, as I’ve always been.

Flex 3: Dynamically Changing Styles

Unfortunately I can’t share the link I have to showcase this but I will share the code used to do it. This is remarkably simple to do.

First, you should know it isn’t as easy as writing CSS and pointing some class source path to the CSS file online. There is only 1 other step you need to perform.

**The Setup Steps**
# In your project, create your CSS (if not already available) to your hearts content.
# Right click on your CSS file in the Flex Navigator. You will see _Compile CSS to SWF_ in the context menu, click it. Your CSS file will be compiled into a loadable “style” swf.
# Upload the “style” swf to some url.

**The Code**
Now that your “style” is created you merely have to tell Flex to load it. There is a delay since the style swf has to be loaded so be mindful.

# Import mx.styles.StyleManager, if needed.
# Add an event listener to your mx:Application (“creationComplete or applicationComplete”:https://www.johncblandii.com/2008/02/flex-3-mxapplicationapplicatio.html). For our purposes this second let’s call it _init()_.
# In _init()_ add the following code: StyleManager.loadStyleDeclarations(“path to your style swf”,true, true);

That’s it. No, seriously…that’s it. ๐Ÿ™‚

There is 1 tid-bit you should know about. The natural thing to do is to then allow your app to change styles after the initial load. Well, not a problem. Use the same code and you’re good to go but there is a gotcha.

bq. StyleManager.unloadStyleDeclarations(“path to previously loaded swf”);

Calling that function will clear all of the previously selected styles. This way if the new style doesn’t fully cover the same styles used in the previous style you won’t see remnants of the old style hanging around (like a background image, etc).

Hope this helps.

FMS & AS3: NetConnection.client and NetStream.client

Ok…I blogged about this a bit ago and wanted to do a quick follow-up post. In the aforementioned post (always wanted to use that $10 word; lol) I pointed out how certain functions (onBWDone, onFCSubscribe, etc) are required in the current client so the server can call them, as needed.

So, the way to do it was to set the myNetConnection.client = this;. Well, that’s still very relavant but it has been SERIOUSLY irritating me on a cleanliness level. Here is why:

public function onBWDone(… rest):void{ … }

Can you tell why it is irritating? PUBLIC!! Now my media connection class has, what seems like, a new function added to the API. ๐Ÿ™ That bites! I’m the only one writing code against it so it isn’t a big issue.

After a few weeks of doing my best to ignore my now public event handler I run across something in LiveDocs.

myNetConnection.client = new Object();

DUH! ๐Ÿ™‚ I thought about it initially but I have each of those handlers dispatching events/making other calls so I didn’t want to mess with that. Seeing as you can say _new Object()_ that means you could say new MyCustomClient() and have it do whatever you want.

Bottom line: You don’t have to set the client property to this but you can set it to a “custom object” or a custom class. Just a quick tidbit.

Flex 3: mx:Application.applicationComplete vs creationComplete

I’m working on a media player in Flex and I ran into an issue.

**Background**
When you click the “Fullscreen” button I change the label to “Exit Fullscreen” and vice versa when you click it again. If you use ESC key to return from fullscreen the label stays the same.

No problem right? I’ll add

bq. stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen);

to my _init()_ function which is called from the _creationComplete_ and I’m done, right?

**Problem**
“_creationComplete”_:https://livedocs.adobe.com/labs/flex3/langref/mx/core/UIComponent.html#event:creationComplete – “Dispatched when the component has finished its construction, property processing, measuring, layout, and drawing.”

Basically, when _creationComplete_ is called the _stage_ object is _null_. Huh? Yep, that’s right…it is null.

**Solution**
I found a “blog post by Raghu”:https://raghuonflex.wordpress.com/2007/03/06/error-on-adding-fullscreenlistener-in-creationcomplete-handler/ where he talked about using the SystemManager. That seems really hack’sh (which he felt the same as well). He then pointed out a “blog post by Wietse Veenstra”:https://www.wietseveenstra.nl/blog/2007/02/12/understanding-the-flex-application-startup-event-order/ which shows the start-up order.

Bottom line, _applicationComplete_ is the event we should use for init’ing our application. _creationComplete_ should be used for init’ing children of the application, if needed.

Hopefully this will help someone as it has helped me. God bless the blogosphere! ๐Ÿ˜‰

SQLite Admin Tool

I found another SQLite admin tool called “SQLite Administrator”:https://sqliteadmin.orbmu2k.de/. This is much more robust (at least it has more icons; lol) than “the last one I chose to use”:https://sqlitebrowser.sourceforge.net/.

If you’re doing AIR dev’, this could be very useful to you. At least it is for me. ๐Ÿ˜‰

NetStream.pause(), .resume(), .togglePause()

I’m thoroughly excited about seeing this in the docs. I’m converting the Limelight Media Player (built in AS2) to Flex 3 and my main connection class manages pausing, stopping, playing, etc. So, in AS2 you have NetStream.pause(value:Boolean). Passing false resumes and true pauses.

I noticed Flex Builder wouldn’t give me any code hints after typing “pause(” but would close the function for me. Hrmm…that’s odd. So, I let it go last week (had other things to focus on) and picked it up today only to find out there are 2 new methods introduced: resume() and togglePause(). SWEET! I had to build my own togglePause() function in my connection class which wasn’t hard but still…native is much greater.

The functions are self-explanatory but if you would like to read more you can see the full doc on LiveDocs.

NetStream.pause()
NetStream.resume()
NetStream.togglePause()

Maybe you don’t share my excitement but that is fine. ๐Ÿ™‚ I’m happy to see progress in the API.

Quick Tip: StringUtil.substitute(str:String, … rest);

I’ve been wanting to do this for a while but never got around to it (like numerous other things). I noticed this in the docs this week and got a bit excited.

If you have used languages like .NET, Java, etc you are probably familiar with something like (in .NET) String.format(“Hi, {0}. I like your {1}.”, “John”, “shoes”);. {0} turns into “John” and {1} into “shoes” which is nice because I could actually make the input string “Hi, {0}. I like your {1}. {0}, may I borrow them?” and it would replace all {0}’s with “John” and so forth.

Adobe snuck in a function to do the same exact thing. Here is an example from LIveDocs:

bq. StringUtil.substitute(“Hi, {0}. I like your {1}. {0}, may I borrow them?”, “John”, “shoes”);.

Kinda cool huh? This is VERY useful and helps keep down the need to concat (which can get ugly).

Just a quick tip…hope it helps.

Flash Media Server 3 Released

“https://www.adobe.com/go/fms”:https://www.adobe.com/go/fms

Nothing much to say here other than GO GET IT! This is an amazing release. I’ve been playing with it locally for a bit and streaming files other than flv is kinda sweet. ๐Ÿ™‚

iTunes Movie Rentals…did they miss the mark?

“Michael Hagel blogged about Apple missing the mark”:https://www.michaelhagel.com/archives/2008/01/itunes-movie-rental-why-apple.php and I can’t say I don’t necessarily disagree. I have a bit of a different perspective though…I’ll be a bit brief. ๐Ÿ™‚

TiVo has had movie rentals for a short while now through Amazon Unbox. I love Unbox but HATE HATE HATE HATE HATE having to wait 2 hours to get my movie (due to the download). I’ve been renting more from Blockbuster lately (like 10 movies in the past few weeks). Everything else about Unbox I love though.

Mike suggested iTunes provide a subscription service. Pay $X.XX/month and get unlimited rentals (3 at a time). Honestly, on IM, I told him “ok…subscription for this would be horribly too great. {other conversation here} i highly doubt they’d ever do that but if they did i’d get an apple tv, mac, iphone, and ipod.”

These movies start in less than 30 seconds. You’re kidding me right? You mean I get a jones for Mrs. Doubtfire and can start watching in less than 30 seconds? AMAZINGLY nice. I wrote TiVo “hate mail” not too long ago about this exact thing (it is simply too easy to do for them to not do it; heck, run it through Flash…I’ll build the player…for a small fee. hehe). ๐Ÿ™‚

So, seriously…them doing that would be crazy. I don’t mean stupid-crazy but more along the lines of…ummm…what’s the world…AMAZING. For Apple folks, or those willing to use something from Apple, they would NEVER need to visit any video store OR subscription service.

Bottom line…+1 for them doing it. I’d get some apple stuff just for this service, unless TiVo comes out with it soon. ๐Ÿ˜‰

Tip – mx:RemoteObject Method Arguments

I’ve used this many times and it saves a good amount of typing and time. I also believe it cleans up your app a bit…let me explain what I’m talking about then I’ll explain why.

bq. <mx:RemoteObject id=”ro” endpoint=”https://localhost:8080/MyService/messagebroker/amf” destination=”blah” showBusyCursor=”true”
result=”handleResult(event)” fault=”handleFault(event)”>
<mx:method name=”getReportData”>
<mx:arguments>
<report>{report}</report>
<someID>{Number(myTextField.text)}</someID>
</mx:arguments>
</mx:method>
</mx:RemoteObject>

This code merely points to the MyService app running on localhost, which is powered by BlazeDS/Spring. I changed a few names because this is work stuff. So, MyService has a DAO (data access object) which returns appropriate data, etc. One of the methods, for this blog post at least (hehe), is named getReportData. It expects an argument named report_ of type ReportDTO (a data transfer object mapped to the appropriate Java class using [RemoteClass(alias=”…”)]) and a number named _someID_.

The big win here is the databinding. The report_ argument is bound to my _report_ variable which, elsewhere in the code, is bound to my form. _someID_ is bound the the value in _myTextField.text_. Using databinding is what speeds up your code and, in my opinion, cleans up your code.

In my mx:Script block I have a method called _getData()_. This method takes the seleted value of a combobox, which is the name of a function, and calls it. So, I have 1 method to kick off any one of my RemoteObject calls. Seeing as each one of my methods has a different method signature (namely _someID_ changes names) and I don’t want to update my Java code to make them the same I have created a perfect scenario to not even worry about the method signatures.

When you create an mx:method and specify all of the arguments through databinding you don’t have to pass them into your method when you invoke a call. Here is what I mean.

bq. ro.getReportData();

That’s it. Yes, _getReportData()_ requires 2 parameters and I passed 0. This is because I already have my values “registered” (bound) in the _mx:arguments_ node.

Sweet, huh? I love it. What? I need to validate my claim on speeding things up for you? Ok…I’m glad you feel this way.

Let’s say you have to call getReportData 10 times in your code. Each call has different data so you would probably create 10 different functions or an if (or switch) statement with 10 blocks. Each one would pretty much do the same thing: update the _report_ variable and call _getReportData(report, Number(myTextField.text))_. That is a whole lot of code duplication.

So, your next argument is: I’ll bind my form to the report object. Good. That’s what I did too. But…you still have to make 10 calls and pass in the arguments. Let’s say the method signature changes. You have to update your entire app to pass in a new variable. Using mx:method/mx:arguments means your entire app call merely calls _getReportData()_ and let’s the _RemoteObject_ worry about the arguments.

Ok…that’s my argument and I’ll do the lawyer thing of allowing myself a way out of this argument. **Disclaimer** This does not apply to ALL situations. ๐Ÿ˜‰

Anyways…enough fun for now…it is 1:49 and I haven’t eaten lunch so I guess I’ll go grab some grub. Hopefully this helps someone.

Custom Metadata in Flex3

This seems to not have received the amount of love it should have so I thought I would help get the word out.

Christophe has a solid blog post about using custom Metadata in AS3 classes. Most don’t understand you can use Reflection in AS3 to build some pretty sweet apps. I used Reflection in an app last year and it was really a sweet way of inspecting my classes, deciding which to load, and a few other goodies it helped me overcome. Basically, no more “if” statement for that specific app. Unfortunately it is an NDA app so I can’t speak on it. ๐Ÿ™

“Read more on Christophe’s blog”:https://coenraets.org/blog/2007/10/annotating-actionscript-classes-with-custom-metadata-simple-orm-framework-for-air/.

“Read more on Reflection”:https://en.wikipedia.org/wiki/Computational_reflection.