Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

Add code examples and scenarios to the dynamic dropdowns section of the Readme #415

Merged
merged 3 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 49 additions & 4 deletions README-source.md
Original file line number Diff line number Diff line change
Expand Up @@ -543,20 +543,65 @@ Additionally, if there is a field that affects the generation of dynamic fields,

### Dynamic Dropdowns

Sometimes, API endpoints require clients to specify a parent object in order to create or access the child resources. Imagine having to specify a company id in order to get a list of employees for that company. Since people don't speak in auto-incremented ID's, it is necessary that Zapier offer a simple way to select that parent using human readable handles.
Sometimes, API endpoints require clients to specify a parent object in order to create or access the child resources. For instance, specifying a spreadsheet id in order to retrieve its worksheets. Since people don't speak in auto-incremented ID's, it is necessary that Zapier offer a simple way to select that parent using human readable handles.

Our solution is to present users a dropdown that is populated by making a live API call to fetch a list of parent objects. We call these special dropdowns "dynamic dropdowns."

To define one, you can provide the `dynamic` property on your field to specify the trigger that should be used to populate the options for the dropdown. The value for the property is a dot-separated concatenation of a trigger's key, the field to use for the value, and the field to use for the label.
To define one you include the `dynamic` property on the `inputFields` object. The value for the property is a dot-separated _string_ concatenation.

```js
[insert-file:./snippets/dynamic-dropdowns.js]
[insert-file:./snippets/dynamic-dropdowns-one.js]
```

In the UI, users will see something like this:
The dot-separated string concatenation follows this pattern:

- The key of the trigger you want to use to power the dropdown. _required_
- The value to be made available in bundle.inputData. _required_
- The human friendly value to be shown on the left of the dropdown in bold. _optional_

In the above code example the dynamic property makes reference to a trigger with a key of project. Assuming the project trigger returns an array of objects and each object contains an id and name key, i.e.

```js
[insert-file:./snippets/dynamic-dropdowns-two.js]
```

The dynamic dropdown would look something like this.
![screenshot of dynamic dropdown in Zap Editor](https://cdn.zapier.com/storage/photos/dd31fa761e0cf9d0abc9b50438f95210.png)

In the first code example the dynamic dropdown is powered by a trigger. You can also use a resource to power a dynamic dropdown. To do this combine the resource key and the resource method using camel case.

```js
[insert-file:./snippets/dynamic-dropdowns-three.js]
```

In some cases you will need to power a dynamic dropdown but do not want to make the Trigger available to the end user. Here it is best practice to create the trigger and set `hidden: true` on it's display object.

```js
[insert-file:./snippets/dynamic-dropdowns-four.js]
```

You can have multiple dynamic dropdowns in a single Trigger or Action. And a dynamic dropdown can depend on the value chosen in another dynamic dropdown when making it's API call. Such as a Spreadsheet and Worksheet dynamic dropdown in a trigger or action. This means you must make sure that the key of the first dynamic dropdown is the same as referenced in the trigger powering the second.

Let's say you have a Worksheet trigger with a `perform` method similar to this.

```js
[insert-file:./snippets/dynamic-dropdowns-five.js]
```

And your New Records trigger has a Spreadsheet and a Worksheet dynamic dropdown. The Spreadsheet dynamic dropdown must have a key of `spreadsheet_id`. When the user selects a spreadsheet via the dynamic dropdown the value chosen is made available in `bundle.inputData`. It will then be passed to the Worksheet trigger when the user clicks on the Worksheet dynamic dropdown.

```js
[insert-file:./snippets/dynamic-dropdowns-six.js]
```

The [Google Sheets](https://zapier.com/apps/google-sheets/integrations#triggers-and-actions) integration is an example of this pattern.

If you want your trigger to perform specific scripting for a dynamic dropdown you will need to make use of `bundle.meta.isFillingDynamicDropdown`. This can be useful if need to make use of [pagination](#whats-the-deal-with-pagination-when-is-it-used-and-how-does-it-work) in the dynamic dropdown to load more options.

```js
[insert-file:./snippets/dynamic-dropdowns-seven.js]
```

### Search-Powered Fields

For fields that take id of another object to create a relationship between the two (EG: a project id for a ticket), you can specify the `search` property on the field to indicate that Zapier needs to prompt the user to setup a Search step to populate the value for this field. Similar to dynamic dropdowns, the value for this property is a dot-separated concatenation of a search's key and the field to use for the value.
Expand Down
189 changes: 184 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1126,11 +1126,62 @@ module.exports = {

### Dynamic Dropdowns

Sometimes, API endpoints require clients to specify a parent object in order to create or access the child resources. Imagine having to specify a company id in order to get a list of employees for that company. Since people don't speak in auto-incremented ID's, it is necessary that Zapier offer a simple way to select that parent using human readable handles.
Sometimes, API endpoints require clients to specify a parent object in order to create or access the child resources. For instance, specifying a spreadsheet id in order to retrieve its worksheets. Since people don't speak in auto-incremented ID's, it is necessary that Zapier offer a simple way to select that parent using human readable handles.

Our solution is to present users a dropdown that is populated by making a live API call to fetch a list of parent objects. We call these special dropdowns "dynamic dropdowns."

To define one, you can provide the `dynamic` property on your field to specify the trigger that should be used to populate the options for the dropdown. The value for the property is a dot-separated concatenation of a trigger's key, the field to use for the value, and the field to use for the label.
To define one you include the `dynamic` property on the `inputFields` object. The value for the property is a dot-separated _string_ concatenation.

```js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be moved into a snippet. create a new file in the snippet directory and then replace this block with [insert-file:./snippets/app-def.js]. See this: https://github.com/zapier/zapier-platform-cli/blame/5dffe11f4322466f873f628c50ce8996c5ba44ca/README-source.md#L183

//...
issue: {
key: 'issue',
//...
create: {
//...
operation: {
inputFields: [
{
key: 'project_id',
required: true,
label: 'This is a dynamic dropdown',
dynamic: 'project.id.name'
}, // will call the trigger with a key of project
{
key: 'title',
required: true,
label: 'Title',
helpText: 'What is the name of the issue?'
}
]
}
}
}

```

The dot-separated string concatenation follows this pattern:

- The key of the trigger you want to use to power the dropdown. _required_
- The value to be made available in bundle.inputData. _required_
- The human friendly value to be shown on the left of the dropdown in bold. _optional_

In the above code example the dynamic property makes reference to a trigger with a key of project. Assuming the project trigger returns an array of objects and each object contains an id and name key, i.e.

```js
[
{ id: '1', name: 'First Option', dateCreated: '01/01/2000' },
{ id: '2', name: 'Second Option', dateCreated: '01/01/2000' },
{ id: '3', name: 'Third Option', dateCreated: '01/01/2000' },
{ id: '4', name: 'Fourth Option', dateCreated: '01/01/2000' }
];

```

The dynamic dropdown would look something like this.
![screenshot of dynamic dropdown in Zap Editor](https://cdn.zapier.com/storage/photos/dd31fa761e0cf9d0abc9b50438f95210.png)

In the first code example the dynamic dropdown is powered by a trigger. You can also use a resource to power a dynamic dropdown. To do this combine the resource key and the resource method using camel case.

```js
const App = {
Expand Down Expand Up @@ -1174,11 +1225,139 @@ const App = {
}
};

```
```

In the UI, users will see something like this:
In some cases you will need to power a dynamic dropdown but do not want to make the Trigger available to the end user. Here it is best practice to create the trigger and set `hidden: true` on it's display object.

![screenshot of dynamic dropdown in Zap Editor](https://cdn.zapier.com/storage/photos/dd31fa761e0cf9d0abc9b50438f95210.png)
```js
const App = {
//...
triggers: {
new_project: {
key: 'project',
noun: 'Project',
// `display` controls the presentation in the Zapier Editor
display: {
label: 'New Project',
description: 'Triggers when a new project is added.',
hidden: true
},
operation: {
perform: projectListRequest
}
},
another_trigger: {
// Another trigger definition...
}
}
};

```

You can have multiple dynamic dropdowns in a single Trigger or Action. And a dynamic dropdown can depend on the value chosen in another dynamic dropdown when making it's API call. Such as a Spreadsheet and Worksheet dynamic dropdown in a trigger or action. This means you must make sure that the key of the first dynamic dropdown is the same as referenced in the trigger powering the second.

Let's say you have a Worksheet trigger with a `perform` method similar to this.

```js
perform: () => {
return z
.request('http://example.com/api/v2/projects.json', {
params: {
spreadsheet_id: bundle.inputData.spreadsheet_id
}
})
.then(response => z.JSON.parse(response.content));
};

```

And your New Records trigger has a Spreadsheet and a Worksheet dynamic dropdown. The Spreadsheet dynamic dropdown must have a key of `spreadsheet_id`. When the user selects a spreadsheet via the dynamic dropdown the value chosen is made available in `bundle.inputData`. It will then be passed to the Worksheet trigger when the user clicks on the Worksheet dynamic dropdown.

```js
const App = {
//...
triggers: {
//...
issue: {
key: 'new_records',
//...
create: {
//...
operation: {
inputFields: [
{
key: 'spreadsheet_id',
required: true,
label: 'Spreadsheet',
dynamic: 'spreadsheet.id.name'
},
{
key: 'worksheet_id',
required: true,
label: 'Worksheet',
dynamic: 'worksheet.id.name'
}
]
}
}
}
}
};

```

The [Google Sheets](https://zapier.com/apps/google-sheets/integrations#triggers-and-actions) integration is an example of this pattern.

If you want your trigger to perform specific scripting for a dynamic dropdown you will need to make use of `bundle.meta.isFillingDynamicDropdown`. This can be useful if need to make use of [pagination](#whats-the-deal-with-pagination-when-is-it-used-and-how-does-it-work) in the dynamic dropdown to load more options.

```js
const App = {
//...
resources: {
project: {
key: 'project',
//...
list: {
//...
operation: {
canPaginate: true,
perform: () => {
if (bundle.meta.isFillingDynamicDropdown) {
// perform pagination request here
} else {
return [{ id: 123, name: 'Project 1' }];
}
}
}
}
},
issue: {
key: 'issue',
//...
create: {
//...
operation: {
inputFields: [
{
key: 'project_id',
required: true,
label: 'Project',
dynamic: 'projectList.id.name'
}, // calls project.list
{
key: 'title',
required: true,
label: 'Title',
helpText: 'What is the name of the issue?'
}
]
}
}
}
}
};

```

### Search-Powered Fields

Expand Down
Loading