Our Blog

Let us find tech solutions together

Jan 27

The Wicket Extensions package provides a neat component called the AutoCompleteTextField.

In a nutshell, this allows you to provide a TextField with a List of Strings and when you start typing, the ones that match the input show up. This is a great component, but consider this scenario:

You have a list of contacts, one of which you want to send an email to. Each person has a unique id and a name. You want to search based on their name, but send the message to their id.

class Person {
  long uuid;
  String displayName;
  String email;
  ...
}

This is not possible with the AutoCompleteTextField, as it uses a list of Strings and will submit whatever is entered in the text field. What you need is to be able to separate the key from the value.

Enter the ObjectAutoCompleteTextField. This is a class from WicketStuff and allows you to provide a List of Objects and tell the AutoCompleteTextField what value should be the displayed value, and what values should be submitted.

Firstly, the markup is the same as a normal text field: <input type="text" wicket:id="toField" />

Now lets build the parts we need:

1. The list of objects:

final List contacts = dao.getContacts();

2. The AutoCompletionChoicesProvider:

AutoCompletionChoicesProvider provider = new AutoCompletionChoicesProvider() {
	private static final long serialVersionUID = 1L;

	public Iterator getChoices(String input) {
		return logic.getMatchingContacts(contacts, input).iterator();
	}
};

This is called whenever the input changes and allows us to get a list of items from our master list that match the input. In this example we already have the list of contacts, so we just need to return an Iterator of the matches for that list. You could use something like this:

public List getMatchingContacts(List contacts, String search) {
	List subList = new ArrayList();

	for(Person p : connections){
		if(StringUtils.startsWithIgnoreCase(p.getDisplayName(), search)) {
			if(subList.size() == Constants.MAX_CONNECTIONS_PER_SEARCH) {
				break;
			}
			subList.add(p);
		}
	}
	return subList;
}

3. The ObjectAutoCompleteRenderer:

ObjectAutoCompleteRenderer renderer = new ObjectAutoCompleteRenderer(){
	private static final long serialVersionUID = 1L;

	protected String getIdValue(Person p) {
		return p.getUuid();
	}
	protected String getTextValue(Person p) {
		return p.getDisplayName();
	}
};

This separates out the key from the value. From the Person class we want to use the uuid as the submitted value and the displayName as the one that shows up in the textfield and we search based on that.

4. Putting it all together is the ObjectAutoCompleteBuilder which takes the provider and sets the renderer.

ObjectAutoCompleteBuilder builder = new ObjectAutoCompleteBuilder(provider);
builder.autoCompleteRenderer(renderer);

5. Finally, we create the ObjectAutoCompleteField from the builder.

ObjectAutoCompleteField autocompleteField = builder.build("toField", new PropertyModel(newMessage, "to"));
final TextField toField = autocompleteField.getSearchTextField();
toField.setRequired(true);
form.add(autocompleteField);

We now have a textfield that allows us to search through a list of items but submit a different value associated with each of those items. autocomplete

Advanced tip: Once we have found an item in the list, it is set into the TextField. If we want to clear the selection, by default the link is a textual [x]. We can override this to be whatever we want, different text, or even an Image. autocomplete_search

To use an icon like in the example above, add something like this to the builder:

builder.searchLinkImage(new ContextRelativeResource("images/cross.png"));
Read more
Jan 04

Being a small business owner, I do a lot of talking on the phone. It could be on the iPhone, but if I’m at the computer it’s usually via Skype. I like to limit my usage of the mouse to as little as possible, so Launchbar is another absolute must. Enter Skype Applescripts for Launchbar.

Simply do one of two things:

  1. Select a contact record, and their phone number, <tab>, Call with Skype
  2. Enter text entry mode ('), type in a phone number with or without country code info, <tab>, Call with Skype

Long ago, I got the Skype Scripts at the Launchbar forums, but it seems those links are gone now. And the scripts that I had, for some reason didn’t respect the country code and automatically assumed the US country code. So entering something like +1 and then a number, would send +1+1 and then the number … obviously Skype didn’t think much of this. Luckily through the power of the internet, I found a macosxhints article which in the comments had a perfect replacement for the “Call with Skype” script. Here’s the original forum posts over at the Objective Development Forums.

I’ve included an archive of the scripts, it should be placed at /Users//Library/Application Support/LaunchBar/Actions/Skype. There are a handful of really awesome scripts aside from the "Call with Skype" including:

  1. Answer Skype Call
  2. Call with Skype
  3. Decline Skype Call
  4. Hang Up Skype Call
  5. Skype Mute Off
  6. Skype Mute On
  7. Toggle Skype Mute
  8. And many many more...

Enjoy!

Skype_Applescripts.zip.

Read more
Dec 30

Mac Pro Box

The box came a day early, on the 29th … and even an hour earlier than originally stated, neat. The machine was unpacked, hooked up to the existing equipment and booted. I should have known what the rest of the experience with this machine was going to be like, by that first boot. It didn’t. It required being shut off and back on again before I would see the glorious Apple logo on screen.

Then the problems really started.

Airport Extreme router, works fine with 2 Macbook Pro’s, an iMac and even an Apple TV, but the Mac Pro while it connected to the N 5GHz network, would drop every other connection as to be completely unusable. Being a dual-band, it had the 2.4GHz network, where the iPhone and other non-N peripherals connected, and it dealt with this one just fine. Of course, having Applecare meant I called right away and worked through this issue with a support agent, who deduced that it wasn’t software and the card was defective. We stayed on a bit more and got an onsite support setup to replace the card (apparently it’s not user-replaceable any longer).

Dutifully, I reconnected my Macbook Pro and started transferring more stuff over to the new machine, and that’s when it started getting, a little wierd. The Apple keyboard would completely miss keys that I had typed, and type others 10x instead of just once. So any chats occurring at the time sounded completely unintelligible. Swapping tabs with the key commands also brought and endless stream of websites or terminal windows zooming by without stopping … the keyboard was screwed. I grabbed another one I knew worked, same issue. I swapped the USB port on the back of the LED display it was plugged into, nada. The magic mouse was also, right-clicking now for every left click.

Something was obviously, very wrong. I called back into Applecare and explained what was going on, and after hearing about my previous issue they suggested we replace the machine entirely. A few transferred calls and confirmations of information and they sent me a FedEx shipping label via email this morning at around 09:30. Thankfully, the local worldwide FedEx dropoff is only a few miles from the house, so I took the box over there, and sent back the lemony flavored Mac Pro with tracking number in hand.

Apparently, when I spoke with the sales support person the previous night, she was able to somehow assure me they could send a new one out within 24 hours of receiving confirmation I’d dropped off the broken one. Being a custom order, I was pretty sure this wasn’t accurate. The rep I spoke to mentioned 2 - 4 business days, so it looks like Tuesday of next week is the earliest I’ll receive the “hopefully” pristine Mac Pro.

I was really hoping to end 2009 with a brand new box, massive speed and power, only to find a machine that didn’t like communicating with the outside world.

It looks like I’ll have to just wish for a Happy New Year.

Read more