Autocomplete Fields for Dynamic Data Services

   MaestroThe UI design product.  |    Form Builder Template Designer |  All versions This feature is related to all versions.

The Maestro Autocomplete Field Component is very flexible, and with that can come complexity. Especially as the Component is now compatible with the newer Transact Functions. We'll show here how to connect Autocomplete Fields to Dynamic Data Services.

Maestro Component Properties

The Autocomplete Field Properties that we'll cover are separated into Data Source, and DDS Configuration. Second DDS Configuration will be reviewed later.

Obviously, you have to add an Autocomplete Field Component to your Form first.

Then expand the Data Source panel on the Component Properties, shown below.

Set the Data Source dropdown to TM Dynamic Data Service, and then for this example set both the Trigger Property Name and the Suggestion List Names to "label". These names are used inside the Transact Dynamic Data Service.

Note: Do not check the "Use Transact Functions" checkbox! That is not compatible with Dynamic Data Services. How to use Transact Functions with Autocomplete Fields is a separate article.

Next, expand the DDS Configuration panel.

The first field is the name of the Transact Dynamic Data Service to be called - type that in. It must match the service name exactly.

Next, click the First Input Field Map control. Type the Key, our sample uses "searchString".

Then click in the Field Reference field, and double-click the Autocomplete Field in the tree on the left side of the dialog. This auto-populates the field data reference - you can type this manually if you like.

The First Response Field Map is set similarly, using "label" as the key.

Note that the response is being mapped back into the Autocomplete Field. In a single-DDS setup, the Autocomplete Field provides input to the DDS, and accepts the selected output!

Save, Build, and Deploy the form to Transact Manager. You should be able to open the form now, but of course the Autocomplete Field's DDS needs to be created.

For this article, a DDS was created that reads a list of animals from a Service Parameter, returning the ones that match what has been typed so far. The source is:

import com.avoka.tm.util.*
import com.avoka.tm.vo.*
import groovy.transform.TypeChecked
import groovy.json.JsonBuilder
import javax.servlet.http.*

@TypeChecked
class FluentDynamicData {

  // Injected at runtime
  public Logger logger

  /*
  * Perform Form Dynamic Data service call.
  *
  * returns: REST response text data
  */
  String invoke(SvcDef svcDef, Txn txn, HttpServletRequest request, User user) {
    String searchString = request.getParameter("searchString")
    logger.info "searchString == ${searchString}"
    String searchData = svcDef.paramsMap["searchData"];
    logger.info "searchData == ${searchData}"
    List searchList = searchData.tokenize(',')
    List baseResults = searchList.findAll { it.startsWith(searchString) }
    logger.info "baseResults == ${baseResults}"
    List results = []
    baseResults.each {
      results.push( ['label':it, 'data':it] )
    }
    logger.info results
    String data = new JsonBuilder(results).toString()
    return data
  }
}

The input into the service is the request parameter "searchString", which was mapped in the First Input Field Map on the DDS Configuration panel, shown above.

The output is the "results" object, which is a List containing maps with a "label" and a "data" elements. The "results" object is converted to JSON and sent back to the Form.

The use of "label" in the return from the service ties in to the use of "label" as the "Suggestion List Names" value in the Data Source panel shown above.

If you test the form now, it should populate with values from the service as you type.

Now, let's add the second DDS

The Autocomplete Field Component can be configured with a second DDS, which is called after the user makes a selection from the options and the output is delivered per the mappings configured. To use this functionality, add a Text Field to the Form.

Then open the Properties for the Autocomplete Field and update the Second DDS Configuration panel. Add a second service name, and use that name to create a new DDS on Transact Manager. Some sample code will be provided below.

The Second Input Field Mapping should be setup to look like the First Input Field Mapping.

The Second Response Field Mapping should be set to map the data keyed "label" to the new Text Field.

For this article, the second DDS, named "DDS Autocomplete2", uses another Service Parameter to find a name based on the first letter of the input "searchString". This creates a little alliteration to send back to the form.

import com.avoka.tm.util.*
import com.avoka.tm.vo.*
import groovy.transform.TypeChecked
import groovy.json.JsonBuilder
import javax.servlet.http.*

@TypeChecked
class FluentDynamicData {
  // Injected at runtime
  public Logger logger
  /*
  * Perform Form Dynamic Data service call.
  *
  * returns: REST response text data
  */
  String invoke(SvcDef svcDef, Txn txn, HttpServletRequest request, User user) {
  String searchString = request.getParameter("searchString")
   logger.info "searchString == ${searchString}"
   String searchData = svcDef.paramsMap["secondarySearchData"];
   logger.info "searchData == ${searchData}"
   List searchList = searchData.tokenize(',')
   List baseResults = searchList.findAll { it.startsWith(searchString[0]) }
   logger.info "baseResults == ${baseResults}"
   List results = []
   results.push( ["label":"${searchString} ${baseResults[0]}", "data":"${searchString} ${baseResults[0]}"] )
   logger.info results
   String data = new JsonBuilder(results).toString()
   return data
  }
}

Save and deploy everything, and the Autocomplete Field should repeatedly call the first DDS to find values that match the typed letters. When a returned value is selected, the second DDS is called and the return displayed in the Text Field.

The Service Parameter value used for searchData is:

Aardvark,Albatross,Alligator,Alpaca,Ant,Anteater,Antelope,Ape,Armadillo,Baboon,Badger,Barracuda,Bat,Bear,Beaver,Bee,Bison,Boar,Butterfly,Camel,Capybara,Caribou,Cassowary,Cat,Caterpillar,Cow,Chamois,Cheetah,Chicken,Chimpanzee,Chinchilla,Chough,Clam,Cobra,Cockroach,Cod,Cormorant,Coyote,Crab,Crane,Crocodile,Crow,Curlew,Deer,Dinosaur,Dog,Dogfish,Dolphin,Donkey,Dotterel,Dove,Dragonfly,Duck,Dugong,Dunlin,Eagle,Echidna,Eel,Eland,Elephant,Elk,Emu,Falcon,Ferret,Finch,Fish,Flamingo,Fly,Fox,Frog,Gaur,Gazelle,Gerbil,Giraffe,Gnat,Gnu,Goat,Goose,Goldfinch,Goldfish,Gorilla,Goshawk,Grasshopper,Grouse,Guanaco,Guinea fowl,Guinea pig,Gull,Hamster,Hare,Hawk,Hedgehog,Heron,Herring,Hippopotamus,Hornet,Horse,Hummingbird,Hyena,Ibex,Ibis,Jackal,Jaguar,Jay,Jellyfish,Kangaroo,Kingfisher,Koala,Komodo Dragon,Kookabura,Kouprey,Kudu,Lapwing,Lark,Lemur,Leopard,Lion,Llama,Lobster,Locust,Loris,Louse,Lyrebird,Magpie,Mallard,Manatee,Mandrill,Mantis,Marten,Meerkat,Mink,Mole,Mongoose,Monkey,Moose,Mouse,Mosquito,Mule,Narwhal,Newt,Nightingale,Octopus,Okapi,Opossum,Oryx,Ostrich,Otter,Owl,Ox,Oyster,Panther,Parrot,Partridge,Peafowl,Pelican,Penguin,Pheasant,Pig,Pigeon,Polar Bear,Pony,Porcupine,Porpoise,Prairie Dog,Quail,Quelea,Quetzal,Rabbit,Raccoon,Rail,Ram,Rat,Raven,Red Panda,Reindeer,Rhinoceros,Rook,Salamander,Salmon,Sand Dollar,Sandpiper,Sardine,Scorpion,Sea Lion,Sea Urchin,Seahorse,Seal,Shark,Sheep,Shrew,Skunk,Snail,Snake,Sparrow,Spider,Spoonbill,Squid,Squirrel,Starling,Stingray,Stinkbug,Stork,Swallow,Swan,Tapir,Tarsier,Termite,Tiger,Toad,Trout,Turkey,Turtle,Viper,Vulture,Wallaby,Walrus,Wasp,Water Buffalo,Weasel,Whale,Wolf,Wolverine,Wombat,Woodcock,Woodpecker,Worm,Wren,Yak,Zebra

And the Service Parameter value used for secondarySearchData is:

Abby,Ace,Allie,Angel,Annie,Apollo,Archie,Athena,Ava,Baby,Bailey,Bailey,Bandit,Baxter,Bear,Beau,Bella,Belle,Benji,Benny,Bentley,
Blue,Bo,Bonnie,Boomer,Brady,Brody,Bruce,Bruno,Brutus,Buddy,Buster,Cali,Callie,Cash,
Chance,Charlie,Charlie,Chase,Chester,Chewy,Chico,Chloe,Cleo,Coco,Coco,Cody,Cookie,
Cooper,Copper,Daisy,Dakota,Delilah,Dexter,Diesel,Dixie,Duke,Ella,Ellie,Emma,
Finn,Fiona,Frankie,George,Georgia,Gigi,Ginger,Gizmo,Grace,Gracie,Gunner,Gus,
Hank,Harley,Harley,Harper,Hazel,Heidi,Henry,Holly,Honey,Hunter,Ivy,Izzy,Jack,
Jackson,Jake,Jasmine,Jasper,Jax,Joey,Josie,King,Kobe,Koda,Kona,Lacey,Lady,Layla,
Leia,Leo,Lexi,Lilly,Lily,Loki,Lola,Louie,Lucky,Lucy,Luke,Lulu,Luna,Mac,Macy,Maddie,
Panut,Peanut,Pearl,Penelope,Penny,Pepper,Phoebe,Piper,Poppy,Prince,Princess,Ranger,
Remi,Rex,Riley,Riley,Rocco,Rocky,Romeo,Roscoe,Rosie,Roxie,Roxy,Ruby,Rudy,Rusty,
Sadie,Sam,Sammy,Samson,Sandy,Sasha,Scout,Scout,Shadow,Shadow,Shelby,Simba,Sophie,
Stella,Sugar,Tank,Teddy,Theo,Thor,Toby,Trixie,Tucker,Tyson,Willow,Winnie,Winston,
Xena,Zeke,Zeus,Ziggy,Zoe,Zoey