Autocomplete Fields for Transact Functions

   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 a Form Function-triggered Transact Function.

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. That seems counter-intuitive, but the other option, Reference Data, does not call any service. To make use of a Transact Function rather than a legacy Dynamic Data Service, check the box for "Use Transact Functions". For this example also set both the Trigger Property Name and the Suggestion List Names to "label". These names are used inside the Transact Dynamic Data Service.

Next, expand the DDS Configuration panel.

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

Similarly, type in the version of the service. The Response Data Key can be left as Response -- it is used in the Groovy code to identify the returned values in the FormFuncResult.

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 Transact Function, and accepts the selected output!

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

For this article, a Transact Function 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.func.*
import com.avoka.tm.svc.*
import com.avoka.tm.util.*
import com.avoka.tm.vo.*
import groovy.transform.TypeChecked
import groovy.json.JsonBuilder
import javax.servlet.http.*

@TypeChecked
class FluentFunction {
  // Injected at runtime
  public Logger logger

  /*
  * Perform Fluent Function call.
  *
  * returns: FuncResult
  */
  FuncResult invoke(FuncParam param) {
    String searchString = param.params.get('searchString').toString()
    logger.info "searchString == ${searchString}"
    String searchData = param.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()
    FormFuncResult result = new FormFuncResult()
    result.data["Response"] = results
    return result
  }
}

The input into the service is the 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 added to the FormFuncRetsult object 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.

Lastly, with Transact Functions, the Function and its Trigger must be added to the Form Version. Navigate Transact Manager to the deployed Form, and in the Version add this Transact Function with a Form Function Trigger and a Sequence of 1.

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

Let's look how to add a second DDS

The Autocomplete Field Component can be configured with a second Transact Function, 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 bottom of the DDS Configuration panel and 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 for the second service.

Note that the DDS Configuration panel has some settings for the second service -- Second Service Version and Second Response Data Key. These two fields are NOT in the Second DDS Configuration Panel!

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 Transact Function, named "TFunc 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.func.*
import com.avoka.tm.svc.*
import com.avoka.tm.util.*
import com.avoka.tm.vo.*
import groovy.transform.TypeChecked
import groovy.json.JsonBuilder
import javax.servlet.http.*

@TypeChecked
class FluentFunction {

// Injected at runtime
public Logger logger

/*
* Perform Fluent Function call.
*
* returns: FuncResult
*/
FuncResult invoke(FuncParam param) {
String searchString = param.params.get('searchString').toString()
logger.info "searchString == ${searchString}"
String searchData = param.svcDef.paramsMap["secondarySearchData"];
logger.info "searchData == ${searchData}"
List searchList = searchData.tokenize(',')
List baseResults = searchList.findAll { it.startsWith(searchString[0]) }
logger.info "baseResults == ${baseResults}"
List myresults = []
String comboName = "${searchString} ${baseResults[0]}".toString()
myresults.push( ['label':comboName, 'data':comboName] )
FormFuncResult result = new FormFuncResult()
result.data["Response"] = myresults
logger.info result.data.Response
return result
}
}

Go back to the Form Version deployed on Transact, and add this new Transact Function to the Form Version. The trigger is Form Function again, and Sequence can be 2.

Save and deploy everything, and the Autocomplete Field should repeatedly call the first Transact Function to find values that match the typed letters. When a returned value is selected, the second Transact Function 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,Maggie,Marley,Marley,Maverick,Max,Maya,Mia,Mila,Millie,Milo,Minnie,Missy,Mocha,Molly,Moose,Murphy,Nala,Nova,Odin,Olive,Oliver,Ollie,Oreo,Oreo,Oscar,Otis,Paisley,Peanut,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