Alpaca provides abstractions for forms, fields, connectors and other types so as to provide a consistent and easy-to-use interface. This interface lets you find other objects in the JSON structure and plug in function handlers that make decisions by drawing from values of other fields.
Every field that renders fundamentally receives an ID
. The ID is a dynamically assigned value of no particular
significance other than that it is unique. Typically, it is something like alpaca123
. Each field or
element that Alpaca renders will utilize this ID to ensure a unique method of look up.
In addition to this ID, every field maintains a name
and a path
. The name is either a
JSON schema property ID (the key for a property) or a JSON array index (for items). The path is a human readable
path into a JSON data element.
For example, suppose you have this JSON data:
{
"author": {
"firstName": "Joe",
"lastName": "Smith",
"grants": [{
"id": "read",
"expiration": "1234567890"
}, {
"id": "write",
"expiration": "1234567890"
}]
}
}
The author's first name can be referenced with a path like this:
author/firstName
The "write" grant expiration time can be referenced like this:
author/grants[1]/expiration
You can look up fields in the rendered Alpaca form using either the ID, the name (property ID) or the path. Typically,
this is done within a postRender
callback:
Here is a pseudo-example that uses a quick and dirty schema for our whack-daddy example from above:
$(domEl).alpaca({
schema: {
"type": "object",
"properties": {
"author": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"grants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"expiration": {
"type": "number"
}
}
}
}
}
}
}
},
postRender: function(field) {
// DO SOMETHING AWESOME HERE
}
});
In the postRender
callback, we get the field instance. This is the top-level field. In the schema above,
the top-level field is an object. Objects and Arrays are Containers in Alpaca and they allow us to do any of the
following:
var authorFirstNameField = field.childrenById["alpaca123"]
var authorFirstNameField = field.childrenByPropertyId["author"].childrenByPropertyId["firstName"]
var authorFirstNameField = field.getControlByPath("author/firstName");
If you have a reference to a field that isn't the top-most field, you can get to the top-most field by using the
top()
function like this:
var authorFirstNameField = grantsArrayField.top().getControlByPath("author/firstName");
Alpaca also maintains a static map of all of the fields that it renders. As such, once Alpaca has rendered, so long
as you have access to the same root Alpaca
object, you can do things like this:
var authorFirstNameField = Alpaca.fieldInstances["alpaca123"];
If you need to look up by path or property ID using a similar static approach, you're out of luck. Instead, you should probably focus on modularizing your code so that references to fields are collected and worked with within the callback handler.
Alpaca marks some of these properties into the DOM for you:
data-alpaca-field-id
gets the Alpaca field IDdata-alpaca-field-name
gets the Alpaca field property IDdata-alpaca-field-path
gets the Alpaca field pathNote that the top-most field will not have the data-alpaca-field-name
attribute.